charyf 0.1.1

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.
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