charyf 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +154 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +18 -0
  6. data/Rakefile +6 -0
  7. data/bin/charyf-debug +7 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/charyf.gemspec +48 -0
  11. data/exe/charyf +4 -0
  12. data/lib/charyf/deps.rb +9 -0
  13. data/lib/charyf/engine/all.rb +22 -0
  14. data/lib/charyf/engine/charyf.rb +5 -0
  15. data/lib/charyf/engine/context.rb +61 -0
  16. data/lib/charyf/engine/controller/actions.rb +29 -0
  17. data/lib/charyf/engine/controller/controller.rb +62 -0
  18. data/lib/charyf/engine/controller/conversation.rb +58 -0
  19. data/lib/charyf/engine/controller/helpers.rb +38 -0
  20. data/lib/charyf/engine/controller/renderers.rb +103 -0
  21. data/lib/charyf/engine/dispatcher/base.rb +121 -0
  22. data/lib/charyf/engine/dispatcher/default.rb +60 -0
  23. data/lib/charyf/engine/intent/intent.rb +54 -0
  24. data/lib/charyf/engine/intent/processors/dummy.rb +30 -0
  25. data/lib/charyf/engine/intent/processors/helpers.rb +32 -0
  26. data/lib/charyf/engine/intent/processors/processor.rb +56 -0
  27. data/lib/charyf/engine/interface/interface.rb +35 -0
  28. data/lib/charyf/engine/interface/program.rb +59 -0
  29. data/lib/charyf/engine/request.rb +32 -0
  30. data/lib/charyf/engine/response.rb +41 -0
  31. data/lib/charyf/engine/session/processors/default.rb +42 -0
  32. data/lib/charyf/engine/session/processors/processor.rb +39 -0
  33. data/lib/charyf/engine/session/session.rb +68 -0
  34. data/lib/charyf/engine/skill/info.rb +24 -0
  35. data/lib/charyf/engine/skill/routing.rb +57 -0
  36. data/lib/charyf/engine/skill/skill.rb +40 -0
  37. data/lib/charyf/engine.rb +3 -0
  38. data/lib/charyf/support/all.rb +4 -0
  39. data/lib/charyf/support/hash.rb +43 -0
  40. data/lib/charyf/support/object.rb +7 -0
  41. data/lib/charyf/support/string.rb +94 -0
  42. data/lib/charyf/support/string_inquirer.rb +17 -0
  43. data/lib/charyf/support.rb +1 -0
  44. data/lib/charyf/utils/all.rb +13 -0
  45. data/lib/charyf/utils/app_engine/extensions.rb +21 -0
  46. data/lib/charyf/utils/app_engine.rb +24 -0
  47. data/lib/charyf/utils/app_loader.rb +38 -0
  48. data/lib/charyf/utils/application/bootstrap.rb +176 -0
  49. data/lib/charyf/utils/application/configuration.rb +51 -0
  50. data/lib/charyf/utils/application.rb +131 -0
  51. data/lib/charyf/utils/charyf.rb +44 -0
  52. data/lib/charyf/utils/cli.rb +14 -0
  53. data/lib/charyf/utils/command/actions.rb +24 -0
  54. data/lib/charyf/utils/command/base.rb +138 -0
  55. data/lib/charyf/utils/command/behavior.rb +81 -0
  56. data/lib/charyf/utils/command/environment_argument.rb +40 -0
  57. data/lib/charyf/utils/command.rb +106 -0
  58. data/lib/charyf/utils/commands/all.rb +6 -0
  59. data/lib/charyf/utils/commands/application/application_command.rb +21 -0
  60. data/lib/charyf/utils/commands/cli/cli_command.rb +115 -0
  61. data/lib/charyf/utils/commands/console/console_command.rb +77 -0
  62. data/lib/charyf/utils/commands/destroy/destroy_command.rb +26 -0
  63. data/lib/charyf/utils/commands/generate/generate_command.rb +31 -0
  64. data/lib/charyf/utils/commands/help/USAGE +9 -0
  65. data/lib/charyf/utils/commands/help/help.rb +20 -0
  66. data/lib/charyf/utils/commands.rb +15 -0
  67. data/lib/charyf/utils/configuration.rb +36 -0
  68. data/lib/charyf/utils/error_handler.rb +26 -0
  69. data/lib/charyf/utils/extension/configurable.rb +41 -0
  70. data/lib/charyf/utils/extension/configuration.rb +63 -0
  71. data/lib/charyf/utils/extension.rb +129 -0
  72. data/lib/charyf/utils/generator/actions.rb +281 -0
  73. data/lib/charyf/utils/generator/base.rb +288 -0
  74. data/lib/charyf/utils/generators/app/USAGE +8 -0
  75. data/lib/charyf/utils/generators/app/app_generator.rb +274 -0
  76. data/lib/charyf/utils/generators/app/templates/Gemfile.erb +20 -0
  77. data/lib/charyf/utils/generators/app/templates/README.md +24 -0
  78. data/lib/charyf/utils/generators/app/templates/app/skill_controller.rb.tt +8 -0
  79. data/lib/charyf/utils/generators/app/templates/bin/charyf +5 -0
  80. data/lib/charyf/utils/generators/app/templates/config/application.rb.tt +32 -0
  81. data/lib/charyf/utils/generators/app/templates/config/boot.rb.tt +4 -0
  82. data/lib/charyf/utils/generators/app/templates/config/chapp.rb.tt +5 -0
  83. data/lib/charyf/utils/generators/app/templates/config/environments/development.rb.tt +2 -0
  84. data/lib/charyf/utils/generators/app/templates/config/environments/production.rb.tt +2 -0
  85. data/lib/charyf/utils/generators/app/templates/config/environments/test.rb.tt +2 -0
  86. data/lib/charyf/utils/generators/app/templates/config/load.rb.tt +17 -0
  87. data/lib/charyf/utils/generators/app/templates/gitignore +18 -0
  88. data/lib/charyf/utils/generators/app_base.rb +277 -0
  89. data/lib/charyf/utils/generators/defaults.rb +75 -0
  90. data/lib/charyf/utils/generators/intents/intents_generator.rb +41 -0
  91. data/lib/charyf/utils/generators/named_base.rb +73 -0
  92. data/lib/charyf/utils/generators/skill/skill_generator.rb +47 -0
  93. data/lib/charyf/utils/generators/skill/templates/controllers/skill_controller.rb.tt +10 -0
  94. data/lib/charyf/utils/generators/skill/templates/module.rb.tt +6 -0
  95. data/lib/charyf/utils/generators/skill/templates/skill.rb.tt +3 -0
  96. data/lib/charyf/utils/generators.rb +187 -0
  97. data/lib/charyf/utils/initializable.rb +95 -0
  98. data/lib/charyf/utils/logger.rb +26 -0
  99. data/lib/charyf/utils/machine.rb +129 -0
  100. data/lib/charyf/utils/parser/en_parser.rb +97 -0
  101. data/lib/charyf/utils/parser/parser.rb +37 -0
  102. data/lib/charyf/utils/ruby_version_check.rb +15 -0
  103. data/lib/charyf/utils/storage/provider.rb +44 -0
  104. data/lib/charyf/utils/strategy.rb +44 -0
  105. data/lib/charyf/utils/utils.rb +64 -0
  106. data/lib/charyf/utils.rb +2 -0
  107. data/lib/charyf/version.rb +19 -0
  108. data/lib/charyf.rb +18 -0
  109. data/lib/locale/en.yml +206 -0
  110. data/todo.md +3 -0
  111. metadata +272 -0
@@ -0,0 +1,281 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Charyf
4
+ module Generators
5
+ module Actions
6
+
7
+ def initialize(*) # :nodoc:
8
+ super
9
+ @in_group = nil
10
+ @after_bundle_callbacks = []
11
+ end
12
+
13
+ # Adds an entry into +Gemfile+ for the supplied gem.
14
+ #
15
+ # gem "rspec", group: :test
16
+ # gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
17
+ # gem "charyf", "1.0", git: "https://github.com/Charyf/charyf-core"
18
+ # gem "RedCloth", ">= 4.1.0", "< 4.2.0"
19
+ def gem(*args)
20
+ options = args.last.is_a?(Hash) ? args.pop : {}
21
+ name, *versions = args
22
+
23
+ # Set the message to be shown in logs. Uses the git repo if one is given,
24
+ # otherwise use name (version).
25
+ parts, message = [quote(name)], name.dup
26
+
27
+ if versions = versions.any? ? versions : options.delete(:version)
28
+ _versions = Array(versions)
29
+ _versions.each do |version|
30
+ parts << quote(version)
31
+ end
32
+ message << " (#{_versions.join(", ")})"
33
+ end
34
+ message = options[:git] if options[:git]
35
+
36
+ log :gemfile, message
37
+
38
+ comment = options.delete(:comment)
39
+
40
+ options.each do |option, value|
41
+ parts << "#{option}: #{quote(value)}"
42
+ end
43
+
44
+ in_root do
45
+ str = "gem #{parts.join(", ")}"
46
+ str = " " + str if @in_group
47
+ str = "\n" + str
48
+ str = "\n#{' ' if @in_group}# #{comment}" + str if comment
49
+ append_file "Gemfile", str, verbose: false
50
+ end
51
+ end
52
+
53
+ # Wraps gem entries inside a group.
54
+ #
55
+ # gem_group :development, :test do
56
+ # gem "rspec"
57
+ # end
58
+ def gem_group(*names, &block)
59
+ name = names.map(&:inspect).join(", ")
60
+ log :gemfile, "group #{name}"
61
+
62
+ in_root do
63
+ append_file "Gemfile", "\ngroup #{name} do", force: true
64
+
65
+ @in_group = true
66
+ instance_eval(&block)
67
+ @in_group = false
68
+
69
+ append_file "Gemfile", "\nend\n", force: true
70
+ end
71
+ end
72
+
73
+ # Add the given source to +Gemfile+
74
+ #
75
+ # If block is given, gem entries in block are wrapped into the source group.
76
+ #
77
+ # add_source "http://gems.github.com/"
78
+ #
79
+ # add_source "http://gems.github.com/" do
80
+ # gem "rspec"
81
+ # end
82
+ def add_source(source, options = {}, &block)
83
+ log :source, source
84
+
85
+ in_root do
86
+ if block
87
+ append_file "Gemfile", "\nsource #{quote(source)} do", force: true
88
+ @in_group = true
89
+ instance_eval(&block)
90
+ @in_group = false
91
+ append_file "Gemfile", "\nend\n", force: true
92
+ else
93
+ prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
94
+ end
95
+ end
96
+ end
97
+
98
+ # Adds a line inside the Application class for <tt>config/application.rb</tt>.
99
+ #
100
+ # If options <tt>:env</tt> is specified, the line is appended to the corresponding
101
+ # file in <tt>config/environments</tt>.
102
+ #
103
+ # environment do
104
+ # "config.action_controller.asset_host = 'cdn.provider.com'"
105
+ # end
106
+ #
107
+ # environment(nil, env: "development") do
108
+ # "config.action_controller.asset_host = 'localhost:3000'"
109
+ # end
110
+ def environment(data = nil, options = {})
111
+ sentinel = "class Application < Charyf::Application\n"
112
+ env_file_sentinel = "Charyf.application.configure do\n"
113
+ data ||= yield if block_given?
114
+
115
+ in_root do
116
+ if options[:env].nil?
117
+ inject_into_file "config/application.rb", optimize_indentation(data, 4), after: sentinel, verbose: false
118
+ else
119
+ Array(options[:env]).each do |env|
120
+ inject_into_file "config/environments/#{env}.rb", optimize_indentation(data, 2), after: env_file_sentinel, verbose: false
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ alias :application :environment
127
+
128
+ # Run a command in git.
129
+ #
130
+ # git :init
131
+ # git add: "this.file that.rb"
132
+ # git add: "onefile.rb", rm: "badfile.cxx"
133
+ def git(commands = {})
134
+ if commands.is_a?(Symbol)
135
+ run "git #{commands}"
136
+ else
137
+ commands.each do |cmd, options|
138
+ run "git #{cmd} #{options}"
139
+ end
140
+ end
141
+ end
142
+
143
+ # # Create a new file in the <tt>lib/</tt> directory. Code can be specified
144
+ # # in a block or a data string can be given.
145
+ # #
146
+ # # lib("crypto.rb") do
147
+ # # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
148
+ # # end
149
+ # #
150
+ # # lib("foreign.rb", "# Foreign code is fun")
151
+ # def lib(filename, data = nil)
152
+ # log :lib, filename
153
+ # data ||= yield if block_given?
154
+ # create_file("lib/#{filename}", optimize_indentation(data), verbose: false)
155
+ # end
156
+
157
+ # # Create a new +Rakefile+ with the provided code (either in a block or a string).
158
+ # #
159
+ # # rakefile("bootstrap.rake") do
160
+ # # project = ask("What is the UNIX name of your project?")
161
+ # #
162
+ # # <<-TASK
163
+ # # namespace :#{project} do
164
+ # # task :bootstrap do
165
+ # # puts "I like boots!"
166
+ # # end
167
+ # # end
168
+ # # TASK
169
+ # # end
170
+ # #
171
+ # # rakefile('seed.rake', 'puts "Planting seeds"')
172
+ # def rakefile(filename, data = nil)
173
+ # log :rakefile, filename
174
+ # data ||= yield if block_given?
175
+ # create_file("lib/tasks/#{filename}", optimize_indentation(data), verbose: false)
176
+ # end
177
+
178
+ # # Create a new initializer with the provided code (either in a block or a string).
179
+ # #
180
+ # # initializer("globals.rb") do
181
+ # # data = ""
182
+ # #
183
+ # # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do |const|
184
+ # # data << "#{const} = :entp\n"
185
+ # # end
186
+ # #
187
+ # # data
188
+ # # end
189
+ # #
190
+ # # initializer("api.rb", "API_KEY = '123456'")
191
+ # def initializer(filename, data = nil)
192
+ # log :initializer, filename
193
+ # data ||= yield if block_given?
194
+ # create_file("config/initializers/#{filename}", optimize_indentation(data), verbose: false)
195
+ # end
196
+ #
197
+ # # Generate something using a generator from Charyf or a plugin.
198
+ # # The second parameter is the argument string that is passed to
199
+ # # the generator or an Array that is joined.
200
+ # #
201
+ # # generate(:authenticated, "user session")
202
+ # def generate(what, *args)
203
+ # log :generate, what
204
+ # argument = args.flat_map(&:to_s).join(" ")
205
+ #
206
+ # in_root {run_ruby_script("bin/charyf generate #{what} #{argument}", verbose: false)}
207
+ # end
208
+ #
209
+ # Registers a callback to be executed after bundle and spring binstubs
210
+ # have run.
211
+ #
212
+ # after_bundle do
213
+ # git add: '.'
214
+ # end
215
+ def after_bundle(&block)
216
+ @after_bundle_callbacks << block
217
+ end
218
+
219
+ private
220
+
221
+ # Define log for backwards compatibility. If just one argument is sent,
222
+ # invoke say, otherwise invoke say_status. Differently from say and
223
+ # similarly to say_status, this method respects the quiet? option given.
224
+ def log(*args) # :doc:
225
+ if args.size == 1
226
+ say args.first.to_s unless options.quiet?
227
+ else
228
+ args << (behavior == :invoke ? :green : :red)
229
+ say_status(*args)
230
+ end
231
+ end
232
+
233
+ #
234
+ # # Runs the supplied command using either "rake ..." or "charyf ..."
235
+ # # based on the executor parameter provided.
236
+ # def execute_command(executor, command, options = {}) # :doc:
237
+ # log executor, command
238
+ # env = options[:env] || ENV["CHARYF_ENV"] || "development"
239
+ # sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
240
+ # config = {verbose: false}
241
+ #
242
+ # config.merge!(capture: options[:capture]) if options[:capture]
243
+ #
244
+ # in_root {run("#{sudo}#{extify(executor)} #{command} CHARYF_ENV=#{env}", config)}
245
+ # end
246
+ #
247
+ # # Add an extension to the given name based on the platform.
248
+ # def extify(name) # :doc:
249
+ # if Gem.win_platform?
250
+ # "#{name}.bat"
251
+ # else
252
+ # name
253
+ # end
254
+ # end
255
+
256
+ # Surround string with single quotes if there is no quotes.
257
+ # Otherwise fall back to double quotes
258
+ def quote(value) # :doc:
259
+ return value.inspect unless value.is_a? String
260
+
261
+ if value.include?("'")
262
+ value.inspect
263
+ else
264
+ "'#{value}'"
265
+ end
266
+ end
267
+ #
268
+ # # Returns optimized string with indentation
269
+ # def optimize_indentation(value, amount = 0) # :doc:
270
+ # return "#{value}\n" unless value.is_a?(String)
271
+ #
272
+ # if value.lines.size > 1
273
+ # value.strip_heredoc.indent(amount)
274
+ # else
275
+ # "#{value.strip.indent(amount)}\n"
276
+ # end
277
+ # end
278
+
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,288 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'thor/group'
5
+ rescue LoadError
6
+ puts "Thor is not available.\nIf you ran this command from a git checkout " \
7
+ "of Charyf, please make sure thor is installed,\nand run this command " \
8
+ "as `ruby #{$0} #{(ARGV | ['--dev']).join(" ")}`"
9
+ exit
10
+ end
11
+
12
+ require_relative 'actions'
13
+
14
+ module Charyf
15
+ module Generators
16
+ class Error < Thor::Error # :nodoc:
17
+ end
18
+
19
+ class Base < Thor::Group
20
+ include Thor::Actions
21
+ include Charyf::Generators::Actions
22
+
23
+ add_runtime_options!
24
+ strict_args_position!
25
+
26
+ # Cache source root and add lib/generators/base/generator/templates to
27
+ # source paths.
28
+ def self.inherited(base) #:nodoc:
29
+ super
30
+
31
+ # Invoke source_root so the default_source_root is set.
32
+ base.source_root
33
+
34
+ if base.name && base.name !~ /Base$/
35
+ Charyf::Generators.subclasses << base
36
+ end
37
+
38
+ end
39
+
40
+ # Tries to get the description from a USAGE file one folder above the command
41
+ # root.
42
+ def self.desc(usage = nil, description = nil, options = {})
43
+ if usage
44
+ super
45
+ else
46
+ @desc ||= ERB.new(File.read(desc_file)).result(binding) if desc_file
47
+ end
48
+ end
49
+
50
+ def self.desc_file(desc_file = nil)
51
+ @desc_file = desc_file if desc_file
52
+
53
+ @desc_file if @desc_file && File.exist?(@desc_file)
54
+ end
55
+
56
+ def self.hook_for(*names, &block)
57
+ options = names.last.is_a?(Hash) ? names.pop : {}
58
+ in_base = options.delete(:in) || base_name
59
+ as_hook = options.delete(:as) || generator_name
60
+
61
+ names.each do |name|
62
+ unless class_options.key?(name)
63
+ defaults = if options[:type] == :boolean
64
+ {}
65
+ elsif [true, false].include?(default_value_for_option(name, options))
66
+ { banner: "", type: :boolean }
67
+ elsif default_value_for_option(name, options).is_a? Array
68
+ { desc: "#{name.to_s} to be invoked", banner: "NAMES", type: :array }
69
+ else
70
+ { desc: "#{name.to_s} to be invoked", banner: "NAME" }
71
+ end
72
+
73
+ class_option(name, defaults.merge!(options))
74
+ end
75
+
76
+ hooks[name] = [ in_base, as_hook ]
77
+ invoke_from_option(name, options, &block)
78
+ end
79
+ end
80
+
81
+ # # Remove a previously added hook.
82
+ # #
83
+ # # remove_hook_for :orm
84
+ # def self.remove_hook_for(*names)
85
+ # remove_invocation(*names)
86
+ #
87
+ # names.each do |name|
88
+ # hooks.delete(name)
89
+ # end
90
+ # end
91
+ #
92
+ # Make class option aware of Charyf::Generators.options
93
+ def self.class_option(name, options = {}) #:nodoc:
94
+ options[:desc] = "Indicates when to generate #{name.to_s.downcase}" unless options.key?(:desc)
95
+ options[:default] = default_value_for_option(name, options)
96
+ super(name, options)
97
+ end
98
+
99
+ # Returns the source root for this generator using default_source_root as default.
100
+ def self.source_root(path = nil)
101
+ @_source_root = path if path
102
+ @_source_root ||= default_source_root || super
103
+ end
104
+
105
+ # Convenience method to get the namespace from the class name. It's the
106
+ # same as Thor default except that the Generator at the end of the class
107
+ # is removed.
108
+ def self.namespace(name = nil)
109
+ return super if name
110
+ @namespace ||= super.sub(/_generator$/, "").sub(/:generators:/, ":")
111
+ end
112
+
113
+ # Convenience method to hide this generator from the available ones when
114
+ # running charyf generator command.
115
+ def self.hide!
116
+ Charyf::Generators.hide_namespace(namespace)
117
+ end
118
+
119
+ protected
120
+
121
+ # Shortcut to invoke with padding and block handling. Use internally by
122
+ # invoke and invoke_from_option class methods.
123
+ def _invoke_for_class_method(klass, command = nil, *args, &block) #:nodoc:
124
+ with_padding do
125
+ if block
126
+ case block.arity
127
+ when 3
128
+ yield(self, klass, command)
129
+ when 2
130
+ yield(self, klass)
131
+ when 1
132
+ instance_exec(klass, &block)
133
+ end
134
+ else
135
+ invoke klass, command, *args
136
+ end
137
+ end
138
+ end
139
+
140
+ # Prepare class invocation to search on Charyf namespace if a previous
141
+ # added hook is being used.
142
+ def self.prepare_for_invocation(name, value) #:nodoc:
143
+ return super unless value.is_a?(String) || value.is_a?(Symbol) #|| value.is_a?(Array)
144
+
145
+ if value && constants = hooks[name]
146
+ value = name if TrueClass === value
147
+ Charyf::Generators.find_by_namespace(value, *constants)
148
+ elsif klass = Charyf::Generators.find_by_namespace(value)
149
+ klass
150
+ else
151
+ super
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ # Check whether the given class names are already taken by user
158
+ # application or Charyf.
159
+ def class_collisions(*class_names)
160
+ return unless behavior == :invoke
161
+
162
+ class_names.flatten.each do |class_name|
163
+ class_name = class_name.to_s
164
+ next if class_name.strip.empty?
165
+
166
+ # Split the class from its module nesting
167
+ nesting = class_name.split("::")
168
+ last_name = nesting.pop
169
+ last = extract_last_module(nesting)
170
+
171
+ if last && last.const_defined?(last_name, false)
172
+ raise Error, "The name '#{class_name}' is either already used in your application " \
173
+ "or reserved by Charyf. Please choose an alternative and run " \
174
+ "this generator again."
175
+ end
176
+ end
177
+ end
178
+
179
+ # Takes in an array of nested modules and extracts the last module
180
+ def extract_last_module(nesting) # :doc:
181
+ nesting.inject(Object) do |last_module, nest|
182
+ break unless last_module.const_defined?(nest, false)
183
+ last_module.const_get(nest)
184
+ end
185
+ end
186
+
187
+ # Wrap block with namespace of current application
188
+ # if namespace exists and is not skipped
189
+ def module_namespacing(&block) # :doc:
190
+ content = capture(&block)
191
+ content = wrap_with_namespace(content) if namespaced?
192
+ concat(content)
193
+ end
194
+
195
+ # Keep hooks configuration that are used on prepare_for_invocation.
196
+ def self.hooks #:nodoc:
197
+ @hooks ||= from_superclass(:hooks, {})
198
+ end
199
+
200
+
201
+ # Returns the default value for the option name given doing a lookup in
202
+ # Charyf::Generators.options.
203
+ def self.default_value_for_option(name, options) # :doc:
204
+ default_for_option(Charyf::Generators.options, name, options, options[:default])
205
+ end
206
+
207
+ # Returns default for the option name given doing a lookup in config.
208
+ def self.default_for_option(config, name, options, default) # :doc:
209
+ if generator_name && (c = config[generator_name.to_sym]) && c.key?(name)
210
+ c[name]
211
+ elsif base_name && (c = config[base_name.to_sym]) && c.key?(name)
212
+ c[name]
213
+ elsif config[:charyf].key?(name)
214
+ config[:charyf][name]
215
+ else
216
+ default
217
+ end
218
+ end
219
+
220
+ # Returns the default source root for a given generator. This is used internally
221
+ # by Charyf to set its generators source root. If you want to customize your source
222
+ # root, you should use source_root.
223
+ def self.default_source_root
224
+ return unless base_name && generator_name
225
+ return unless default_generator_root
226
+ path = File.join(default_generator_root, "templates")
227
+ path if File.exist?(path)
228
+ end
229
+
230
+ # Returns the base root for a common set of generators. This is used to dynamically
231
+ # guess the default source root.
232
+ def self.base_root
233
+ __dir__
234
+ end
235
+
236
+ # Use Charyf default banner.
237
+ def self.banner # :doc:
238
+ "charyf generate #{namespace.sub(/^charyf:/, '')} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
239
+ end
240
+
241
+ # Sets the base_name taking into account the current class namespace.
242
+ def self.base_name # :doc:
243
+ @base_name ||= begin
244
+ if base = name.to_s.split("::").first
245
+ base.underscore
246
+ end
247
+ end
248
+ end
249
+
250
+ # Removes the namespaces and get the generator name. For example,
251
+ # Charyf::Generators::SkillGenerator will return "skill" as generator name.
252
+ def self.generator_name # :doc:
253
+ @generator_name ||= begin
254
+ if generator = name.to_s.split("::").last
255
+ generator.sub!(/Generator$/, "")
256
+ generator.underscore
257
+ end
258
+ end
259
+ end
260
+
261
+ # # Small macro to add ruby as an option to the generator with proper
262
+ # # default value plus an instance helper method called shebang.
263
+ def self.add_shebang_option! # :doc:
264
+ class_option :ruby, type: :string, aliases: "-r", default: Thor::Util.ruby_command,
265
+ desc: "Path to the Ruby binary of your choice", banner: "PATH"
266
+
267
+ no_tasks {
268
+ define_method :shebang do
269
+ @shebang ||= begin
270
+ command = if options[:ruby] == Thor::Util.ruby_command
271
+ "/usr/bin/env #{File.basename(Thor::Util.ruby_command)}"
272
+ else
273
+ options[:ruby]
274
+ end
275
+ "#!#{command}"
276
+ end
277
+ end
278
+ }
279
+ end
280
+
281
+ def self.default_generator_root # :doc:
282
+ path = File.expand_path(File.join('..', 'generators', generator_name), base_root)
283
+ path if File.exist?(path)
284
+ end
285
+
286
+ end
287
+ end
288
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ The 'charyf new' command creates a new Charyf application with a default
3
+ directory structure and configuration at the path you specify.
4
+
5
+ Example
6
+ charyf new ~/Code/Ruby/weblog
7
+
8
+ This generates a skeletal Charyf installation in ~/Code/Ruby/weblog.