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,277 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ require_relative '../generator/base'
6
+ require_relative '../generators'
7
+ require_relative '../../version'
8
+
9
+ require_relative 'defaults'
10
+
11
+ module Charyf
12
+ module Generators
13
+ module ActionMethods # :nodoc:
14
+ attr_reader :options
15
+
16
+ def initialize(generator)
17
+ @generator = generator
18
+ @options = generator.options
19
+ end
20
+
21
+ private
22
+ %w(destination_root template copy_file directory empty_directory inside
23
+ empty_directory_with_keep_file keep_file create_file chmod run shebang
24
+ gem_group gem gemfile_entries).each do |method|
25
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
26
+ def #{method}(*args, &block)
27
+ @generator.send(:#{method}, *args, &block)
28
+ end
29
+ RUBY
30
+ end
31
+ end
32
+
33
+ class AppBase < Base # :nodoc:
34
+ add_shebang_option!
35
+
36
+ argument :app_path, type: :string
37
+
38
+ def self.strict_args_position
39
+ false
40
+ end
41
+
42
+ def self.add_shared_options_for(name)
43
+
44
+ class_option :intent_processors, type: :array, aliases: "-ip", default: Defaults::SETTINGS[:intents],
45
+ desc: "Set of intent intent processors to be included in installation" + Defaults.intents_desc,
46
+ group: :strategies
47
+
48
+ class_option :storage_provider, type: :string, aliases: "-sp", default: Defaults::SETTINGS[:storage],
49
+ desc: "Storage provider to be installed by default." + Defaults.storage_desc,
50
+ group: :strategies
51
+
52
+
53
+
54
+ class_option :skip_gemfile, type: :boolean, default: false,
55
+ desc: "Don't create a Gemfile"
56
+
57
+ class_option :skip_git, type: :boolean, aliases: "-G", default: false,
58
+ desc: "Skip .gitignore file"
59
+
60
+ class_option :skip_keeps, type: :boolean, default: false,
61
+ desc: "Skip source control .keep files"
62
+
63
+ class_option :lib, type: :boolean, aliases: "-L", default: false,
64
+ desc: "Install Charyf as library to existing project"
65
+
66
+ class_option :dev, type: :boolean, default: false,
67
+ desc: "Setup the #{name} with Gemfile pointing to your Charyf checkout"
68
+
69
+ class_option :edge, type: :boolean, default: false,
70
+ desc: "Setup the #{name} with Gemfile pointing to Charyf repository"
71
+
72
+ class_option :help, type: :boolean, aliases: "-h", group: :charyf,
73
+ desc: "Show this help message and quit"
74
+ end
75
+
76
+ def initialize(*args)
77
+ @gem_filter = lambda { |gem| true }
78
+ @extra_entries = []
79
+ super
80
+ end
81
+ #
82
+ private
83
+
84
+ def gemfile_entry(name, *args) # :doc:
85
+ options = args.extract_options!
86
+ version = args.first
87
+ github = options[:github]
88
+ path = options[:path]
89
+
90
+ if github
91
+ @extra_entries << GemfileEntry.github(name, github)
92
+ elsif path
93
+ @extra_entries << GemfileEntry.path(name, path)
94
+ else
95
+ @extra_entries << GemfileEntry.version(name, version)
96
+ end
97
+ self
98
+ end
99
+
100
+ def gemfile_entries # :doc:
101
+ [charyf_gemfile_entry,
102
+ intents_gemfile_entries,
103
+ storage_gemfile_entries,
104
+ @extra_entries].flatten.find_all(&@gem_filter)
105
+ end
106
+
107
+ def add_gem_entry_filter # :doc:
108
+ @gem_filter = lambda { |next_filter, entry|
109
+ yield(entry) && next_filter.call(entry)
110
+ }.curry[@gem_filter]
111
+ end
112
+
113
+ def builder # :doc:
114
+ @builder ||= begin
115
+ builder_class = get_builder_class
116
+ builder_class.include(ActionMethods)
117
+ builder_class.new(self)
118
+ end
119
+ end
120
+
121
+ def build(meth, *args) # :doc:
122
+ builder.send(meth, *args) if builder.respond_to?(meth)
123
+ end
124
+
125
+ def create_root # :doc:
126
+ valid_const?
127
+
128
+ empty_directory "."
129
+ FileUtils.cd(destination_root) unless options[:pretend]
130
+ end
131
+
132
+ def set_default_accessors! # :doc:
133
+ self.destination_root = File.expand_path(app_path, destination_root)
134
+
135
+ if options[:lib]
136
+ # Instantiate app name beforehand
137
+ app_name
138
+
139
+ self.destination_root = File.expand_path('charyf', destination_root)
140
+ end
141
+ end
142
+
143
+ def keeps? # :doc:
144
+ !options[:skip_keeps]
145
+ end
146
+
147
+ def lib?
148
+ options[:lib]
149
+ end
150
+
151
+ def intents_details
152
+ Defaults::INTENT_PROCESSORS.select { |ip| options[:intent_processors].include?(ip.to_s) }
153
+ end
154
+
155
+ def storage_details
156
+ storage = Defaults::STORAGE_PROVIDERS[options[:storage_provider].to_sym]
157
+ $stderr.puts "Unknown storage provider '#{options[:storage_provider]}'" unless storage
158
+
159
+ storage
160
+ end
161
+
162
+ class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
163
+ def initialize(name, version, comment, options = {}, commented_out = false)
164
+ super
165
+ end
166
+
167
+ def self.github(name, github, branch = nil, comment = nil)
168
+ if branch
169
+ new(name, nil, comment, github: github, branch: branch)
170
+ else
171
+ new(name, nil, comment, github: github)
172
+ end
173
+ end
174
+
175
+ def self.version(name, version, comment = nil)
176
+ new(name, version, comment)
177
+ end
178
+
179
+ def self.path(name, path, comment = nil)
180
+ new(name, nil, comment, path: path)
181
+ end
182
+
183
+ def version
184
+ version = super
185
+
186
+ if version.is_a?(Array)
187
+ version.join("', '")
188
+ else
189
+ version
190
+ end
191
+ end
192
+ end
193
+
194
+ def charyf_gemfile_entry
195
+ if options.dev?
196
+ [
197
+ GemfileEntry.path("charyf", Charyf::Generators::CHARYF_DEV_PATH)
198
+ ]
199
+ elsif options.edge?
200
+ [
201
+ GemfileEntry.github("charyf", "Charyf/charyf-core", nil,
202
+ "Bundle edge Charyf instead: gem 'charyf', github: 'charyf/charyf-core'")
203
+ ]
204
+ else
205
+ [GemfileEntry.version("charyf",
206
+ charyf_version_specifier)]
207
+ end
208
+ end
209
+
210
+ def intents_gemfile_entries
211
+ Defaults::INTENT_PROCESSORS.values.map do |details|
212
+ GemfileEntry.version(details[:gem], details[:gem_version], 'Intent processor [generated]')
213
+ end
214
+ end
215
+
216
+ def storage_gemfile_entries
217
+ Defaults::STORAGE_PROVIDERS.values.map do |details|
218
+ GemfileEntry.version(details[:gem], details[:gem_version], 'Storage provider [generated]')
219
+ end
220
+ end
221
+
222
+ def charyf_version_specifier(gem_version = Charyf.gem_version)
223
+ if gem_version.segments.size == 3 || gem_version.release.segments.size == 3
224
+ # ~> 1.2.3
225
+ # ~> 1.2.3.pre4
226
+ "~> #{gem_version}"
227
+ else
228
+ # ~> 1.2.3, >= 1.2.3.4
229
+ # ~> 1.2.3, >= 1.2.3.4.pre5
230
+ patch = gem_version.segments[0, 3].join(".")
231
+ ["~> #{patch}", ">= #{gem_version}"]
232
+ end
233
+ end
234
+
235
+ def bundle_command(command)
236
+ say_status :run, "bundle #{command}"
237
+
238
+ # We are going to shell out rather than invoking Bundler::CLI.new(command)
239
+ # because `charyf new` loads the Thor gem and on the other hand bundler uses
240
+ # its own vendored Thor, which could be a different version. Running both
241
+ # things in the same process is a recipe for a night with paracetamol.
242
+ #
243
+ # We unset temporary bundler variables to load proper bundler and Gemfile.
244
+ #
245
+ # Thanks to James Tucker for the Gem tricks involved in this call.
246
+ _bundle_command = Gem.bin_path("bundler", "bundle")
247
+
248
+ require "bundler"
249
+ Bundler.with_clean_env do
250
+ full_command = %Q["#{Gem.ruby}" "#{_bundle_command}" #{command}]
251
+ if options[:quiet]
252
+ system(full_command, out: File::NULL)
253
+ else
254
+ system(full_command)
255
+ end
256
+ end
257
+ end
258
+
259
+ def bundle_install?
260
+ !(options[:skip_gemfile] || options[:skip_bundle] || options[:pretend])
261
+ end
262
+
263
+ def run_bundle
264
+ bundle_command("install") if bundle_install?
265
+ end
266
+
267
+ def empty_directory_with_keep_file(destination, config = {})
268
+ empty_directory(destination, config)
269
+ keep_file(destination)
270
+ end
271
+
272
+ def keep_file(destination)
273
+ create_file("#{destination}/.keep") if keeps?
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,75 @@
1
+ module Charyf
2
+ module Generators
3
+ module Defaults
4
+ extend self
5
+
6
+ SETTINGS = {
7
+ storage: 'memory',
8
+ intents: ['adapt']
9
+ }
10
+
11
+ STORAGE_PROVIDERS = {
12
+ memory: {
13
+ gem: 'charyf-memory-storage',
14
+ gem_version: ['>= 0.1'],
15
+ require: 'charyf/memory_storage',
16
+ desc: <<-EOM
17
+ Memory storage does not provide permanent storage as the contract may require
18
+ but delivers enough capabilities for development and testing.
19
+ Should not be used on production environments as it is not persisted.
20
+ EOM
21
+ }
22
+ }
23
+
24
+ INTENT_PROCESSORS = {
25
+ adapt: {
26
+ gem: 'adapt-charyf',
27
+ gem_version: ['>= 0.2'],
28
+ require: 'adapt-charyf',
29
+ desc: <<-EOM
30
+ Ruby wrapper around python library from mycroft [adapt]
31
+ It uses building blocks as regexps or small expressions to define and determine intents.
32
+ see more at: https://github.com/Charyf/charyf-adapt-processor
33
+ EOM
34
+ }
35
+ }
36
+
37
+ def intents_desc
38
+ desc = "\n"
39
+ desc << "Here is a list of currently available and supported intent processors, \nthat can be enabled during installation"
40
+ desc << "\nIf your processor isn't listed here, you can change it later in your project settings"
41
+
42
+ desc << desc(INTENT_PROCESSORS)
43
+
44
+ "\t" + desc.gsub("\n", "\n\t")
45
+ end
46
+
47
+ def storage_desc
48
+ desc = "\n"
49
+ desc << "Here is a list of currently available and supported storage providers, \nthat can be enabled during installation"
50
+ desc << "\nIf your provider isn't listed here, you can change it later in your project settings"
51
+
52
+ desc << desc(STORAGE_PROVIDERS)
53
+
54
+ desc
55
+
56
+ "\t" + desc.gsub("\n", "\n\t")
57
+ end
58
+
59
+ private
60
+
61
+ def desc(group)
62
+ desc = ""
63
+
64
+ group.each do |name, details|
65
+ desc << "\n" + name.to_s
66
+ desc << "\n\tGem: #{details[:gem]} #{details[:gem_version]}\n"
67
+ desc << "\t" + details[:desc].strip.gsub("\n", "\n\t")
68
+ end
69
+
70
+ desc
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../app_base'
4
+ require_relative '../named_base'
5
+
6
+ require_relative '../../generators'
7
+
8
+ require_relative '../../../support'
9
+
10
+ module Charyf
11
+ module Generators
12
+ class IntentsGenerator < NamedBase # :nodoc:
13
+
14
+ def try
15
+ intent_generators.each do |generator_name|
16
+ names = generator_name(generator_name).to_s.split(":")
17
+ klass = Charyf::Generators.find_by_namespace(names.pop, names.any? && names.join(":"))
18
+
19
+ if klass
20
+ say_status behavior, generator_name(generator_name), :green
21
+
22
+ invoke generator_name(generator_name), [name], options, behavior: behavior
23
+ else
24
+ say_status behavior, "#{generator_name(generator_name)} generator not found", :red
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def intent_generators
32
+ Charyf::Generators.options[:intents].keys.map(&:downcase)
33
+ end
34
+
35
+ def generator_name(intent_processor_name)
36
+ "#{intent_processor_name}:intent"
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../generator/base'
4
+
5
+ module Charyf
6
+ module Generators
7
+ class NamedBase < Base
8
+ argument :name, type: :string
9
+
10
+ def initialize(args, *options) #:nodoc:
11
+ # Unfreeze name in case it's given as a frozen string
12
+ args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
13
+ super
14
+ assign_names!(name)
15
+ end
16
+
17
+ private
18
+
19
+ def class_path # :doc:
20
+ @class_path
21
+ end
22
+
23
+ def module_path
24
+ class_path[0...-1]
25
+ end
26
+
27
+ def module_file_name
28
+ class_path.last
29
+ end
30
+
31
+ def file_name
32
+ @file_name
33
+ end
34
+
35
+ def skill_content_path
36
+ class_path.dup.push(file_name)
37
+ end
38
+
39
+ def empty_directory_with_keep_file(destination, config = {})
40
+ empty_directory(destination, config)
41
+ create_file("#{destination}/.keep")
42
+ end
43
+
44
+ def class_name # :doc:
45
+ (class_path + [file_name]).map!(&:camelize).join("::")
46
+ end
47
+
48
+ def assign_names!(name)
49
+ @class_path = name.include?("/") ? name.split("/") : name.split("::")
50
+ @class_path.map!(&:underscore)
51
+ @file_name = @class_path.pop
52
+ end
53
+
54
+ # Add a class collisions name to be checked on class initialization. You
55
+ # can supply a hash with a :prefix or :suffix to be tested.
56
+ #
57
+ # ==== Examples
58
+ #
59
+ # check_class_collision suffix: "Decorator"
60
+ #
61
+ # If the generator is invoked with class name Admin, it will check for
62
+ # the presence of "AdminDecorator".
63
+ #
64
+ def self.check_class_collision(options = {}) # :doc:
65
+ define_method "check_class_collision_#{options[:suffix]}_#{options[:prefix]}" do
66
+ name = class_name
67
+
68
+ class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../named_base'
4
+
5
+ require_relative '../../../support'
6
+
7
+ module Charyf
8
+ module Generators
9
+ class SkillGenerator < NamedBase # :nodoc:
10
+
11
+ check_class_collision
12
+ check_class_collision suffix: '::BaseController'
13
+
14
+ def create_module_file
15
+ return if class_path.empty?
16
+ template 'module.rb', File.join('app/skills', module_path.join('/'), "#{module_file_name}.rb") if behavior == :invoke
17
+ end
18
+
19
+ def create_skill_file
20
+ template 'skill.rb', File.join('app/skills', class_path, "#{file_name}.rb")
21
+ end
22
+
23
+ def controller
24
+ empty_directory File.join('app/skills', skill_content_path, 'controllers')
25
+
26
+ template 'controllers/skill_controller.rb', File.join('app/skills', skill_content_path, 'controllers', 'base_controller.rb')
27
+ end
28
+
29
+ def intents
30
+ empty_directory File.join('app/skills', skill_content_path, 'intents')
31
+ end
32
+
33
+ def responses
34
+ empty_directory File.join('app/skills', skill_content_path, 'responses')
35
+
36
+ empty_directory File.join('app/skills', skill_content_path, 'responses', 'base')
37
+ end
38
+
39
+ def initializers
40
+ empty_directory File.join('app/skills', skill_content_path, 'initializers')
41
+ end
42
+
43
+ hook_for :intents
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,10 @@
1
+ class <%= "#{class_name}::BaseController" -%> < SkillController
2
+
3
+ def example
4
+ msg = "I am an example response for skill '<%= class_name.gsub("::", " ") -%>'"
5
+ msg << "\nFind me in #{__FILE__}"
6
+
7
+ reply(text: msg)
8
+ end
9
+
10
+ end
@@ -0,0 +1,6 @@
1
+ <% padding = 0 -%>
2
+ <% module_path + [module_file_name].each do |module_part| -%>
3
+ <%= " " * padding -%>module <%= module_part.camelize %>
4
+ <%= " " * padding -%>end
5
+ <% padding += 1 -%>
6
+ <% end -%>
@@ -0,0 +1,3 @@
1
+ class <%= class_name -%> < Charyf::Skill::Base
2
+ skill_name '<%= class_name.gsub("::", " ") -%>'
3
+ end