charyf 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +154 -0
- data/LICENSE.txt +21 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/bin/charyf-debug +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/charyf.gemspec +48 -0
- data/exe/charyf +4 -0
- data/lib/charyf/deps.rb +9 -0
- data/lib/charyf/engine/all.rb +22 -0
- data/lib/charyf/engine/charyf.rb +5 -0
- data/lib/charyf/engine/context.rb +61 -0
- data/lib/charyf/engine/controller/actions.rb +29 -0
- data/lib/charyf/engine/controller/controller.rb +62 -0
- data/lib/charyf/engine/controller/conversation.rb +58 -0
- data/lib/charyf/engine/controller/helpers.rb +38 -0
- data/lib/charyf/engine/controller/renderers.rb +103 -0
- data/lib/charyf/engine/dispatcher/base.rb +121 -0
- data/lib/charyf/engine/dispatcher/default.rb +60 -0
- data/lib/charyf/engine/intent/intent.rb +54 -0
- data/lib/charyf/engine/intent/processors/dummy.rb +30 -0
- data/lib/charyf/engine/intent/processors/helpers.rb +32 -0
- data/lib/charyf/engine/intent/processors/processor.rb +56 -0
- data/lib/charyf/engine/interface/interface.rb +35 -0
- data/lib/charyf/engine/interface/program.rb +59 -0
- data/lib/charyf/engine/request.rb +32 -0
- data/lib/charyf/engine/response.rb +41 -0
- data/lib/charyf/engine/session/processors/default.rb +42 -0
- data/lib/charyf/engine/session/processors/processor.rb +39 -0
- data/lib/charyf/engine/session/session.rb +68 -0
- data/lib/charyf/engine/skill/info.rb +24 -0
- data/lib/charyf/engine/skill/routing.rb +57 -0
- data/lib/charyf/engine/skill/skill.rb +40 -0
- data/lib/charyf/engine.rb +3 -0
- data/lib/charyf/support/all.rb +4 -0
- data/lib/charyf/support/hash.rb +43 -0
- data/lib/charyf/support/object.rb +7 -0
- data/lib/charyf/support/string.rb +94 -0
- data/lib/charyf/support/string_inquirer.rb +17 -0
- data/lib/charyf/support.rb +1 -0
- data/lib/charyf/utils/all.rb +13 -0
- data/lib/charyf/utils/app_engine/extensions.rb +21 -0
- data/lib/charyf/utils/app_engine.rb +24 -0
- data/lib/charyf/utils/app_loader.rb +38 -0
- data/lib/charyf/utils/application/bootstrap.rb +176 -0
- data/lib/charyf/utils/application/configuration.rb +51 -0
- data/lib/charyf/utils/application.rb +131 -0
- data/lib/charyf/utils/charyf.rb +44 -0
- data/lib/charyf/utils/cli.rb +14 -0
- data/lib/charyf/utils/command/actions.rb +24 -0
- data/lib/charyf/utils/command/base.rb +138 -0
- data/lib/charyf/utils/command/behavior.rb +81 -0
- data/lib/charyf/utils/command/environment_argument.rb +40 -0
- data/lib/charyf/utils/command.rb +106 -0
- data/lib/charyf/utils/commands/all.rb +6 -0
- data/lib/charyf/utils/commands/application/application_command.rb +21 -0
- data/lib/charyf/utils/commands/cli/cli_command.rb +115 -0
- data/lib/charyf/utils/commands/console/console_command.rb +77 -0
- data/lib/charyf/utils/commands/destroy/destroy_command.rb +26 -0
- data/lib/charyf/utils/commands/generate/generate_command.rb +31 -0
- data/lib/charyf/utils/commands/help/USAGE +9 -0
- data/lib/charyf/utils/commands/help/help.rb +20 -0
- data/lib/charyf/utils/commands.rb +15 -0
- data/lib/charyf/utils/configuration.rb +36 -0
- data/lib/charyf/utils/error_handler.rb +26 -0
- data/lib/charyf/utils/extension/configurable.rb +41 -0
- data/lib/charyf/utils/extension/configuration.rb +63 -0
- data/lib/charyf/utils/extension.rb +129 -0
- data/lib/charyf/utils/generator/actions.rb +281 -0
- data/lib/charyf/utils/generator/base.rb +288 -0
- data/lib/charyf/utils/generators/app/USAGE +8 -0
- data/lib/charyf/utils/generators/app/app_generator.rb +274 -0
- data/lib/charyf/utils/generators/app/templates/Gemfile.erb +20 -0
- data/lib/charyf/utils/generators/app/templates/README.md +24 -0
- data/lib/charyf/utils/generators/app/templates/app/skill_controller.rb.tt +8 -0
- data/lib/charyf/utils/generators/app/templates/bin/charyf +5 -0
- data/lib/charyf/utils/generators/app/templates/config/application.rb.tt +32 -0
- data/lib/charyf/utils/generators/app/templates/config/boot.rb.tt +4 -0
- data/lib/charyf/utils/generators/app/templates/config/chapp.rb.tt +5 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/development.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/production.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/test.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/load.rb.tt +17 -0
- data/lib/charyf/utils/generators/app/templates/gitignore +18 -0
- data/lib/charyf/utils/generators/app_base.rb +277 -0
- data/lib/charyf/utils/generators/defaults.rb +75 -0
- data/lib/charyf/utils/generators/intents/intents_generator.rb +41 -0
- data/lib/charyf/utils/generators/named_base.rb +73 -0
- data/lib/charyf/utils/generators/skill/skill_generator.rb +47 -0
- data/lib/charyf/utils/generators/skill/templates/controllers/skill_controller.rb.tt +10 -0
- data/lib/charyf/utils/generators/skill/templates/module.rb.tt +6 -0
- data/lib/charyf/utils/generators/skill/templates/skill.rb.tt +3 -0
- data/lib/charyf/utils/generators.rb +187 -0
- data/lib/charyf/utils/initializable.rb +95 -0
- data/lib/charyf/utils/logger.rb +26 -0
- data/lib/charyf/utils/machine.rb +129 -0
- data/lib/charyf/utils/parser/en_parser.rb +97 -0
- data/lib/charyf/utils/parser/parser.rb +37 -0
- data/lib/charyf/utils/ruby_version_check.rb +15 -0
- data/lib/charyf/utils/storage/provider.rb +44 -0
- data/lib/charyf/utils/strategy.rb +44 -0
- data/lib/charyf/utils/utils.rb +64 -0
- data/lib/charyf/utils.rb +2 -0
- data/lib/charyf/version.rb +19 -0
- data/lib/charyf.rb +18 -0
- data/lib/locale/en.yml +206 -0
- data/todo.md +3 -0
- metadata +272 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command/base'
|
4
|
+
require_relative '../../command/environment_argument'
|
5
|
+
|
6
|
+
module Charyf
|
7
|
+
class CLI
|
8
|
+
|
9
|
+
def self.start
|
10
|
+
self.new.start
|
11
|
+
end
|
12
|
+
|
13
|
+
def start
|
14
|
+
build_interface
|
15
|
+
print_intro
|
16
|
+
|
17
|
+
begin
|
18
|
+
loop do
|
19
|
+
detect request_input
|
20
|
+
end
|
21
|
+
rescue Interrupt
|
22
|
+
puts "\n"
|
23
|
+
puts 'Exiting CLI'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def print_intro
|
30
|
+
puts <<-EOM
|
31
|
+
Initialized #{Charyf.env} environment (Charyf #{Charyf.version})
|
32
|
+
Welcome to the Charyf CLI Interface.
|
33
|
+
Type ":help" for ist of available commands
|
34
|
+
To exit pres ctrl + c
|
35
|
+
EOM
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_help
|
39
|
+
puts <<-EOM
|
40
|
+
:help prints this help
|
41
|
+
:exit quit the charyf cli
|
42
|
+
alternatively use ctrl + d (EOM)
|
43
|
+
or ctrl + c (KILL)
|
44
|
+
EOM
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_input
|
48
|
+
print '[User] '
|
49
|
+
input = gets
|
50
|
+
exit unless input
|
51
|
+
|
52
|
+
input.strip
|
53
|
+
end
|
54
|
+
|
55
|
+
def cli_print(obj)
|
56
|
+
print '[Charyf] '
|
57
|
+
puts obj
|
58
|
+
puts ' - - - '
|
59
|
+
end
|
60
|
+
|
61
|
+
def detect(utterance)
|
62
|
+
if utterance[0] == ':'
|
63
|
+
process_command utterance[1..-1]
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
request = @interface.request
|
68
|
+
request.text = utterance
|
69
|
+
|
70
|
+
@interface.process(request)
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def process_command(command)
|
75
|
+
case command
|
76
|
+
when 'help'
|
77
|
+
print_help
|
78
|
+
when 'exit'
|
79
|
+
exit(0)
|
80
|
+
else
|
81
|
+
puts 'Unknown command'
|
82
|
+
print_help
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def build_interface
|
88
|
+
# TODO - dependency on bad "package"
|
89
|
+
@interface = Charyf::Interface::Program.create("cli_#{Process.pid}", Proc.new { |response| cli_print(response.text) })
|
90
|
+
$stderr.puts "Created program interface for process ##{Process.pid}."
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
module Command
|
96
|
+
class CliCommand < Base # :nodoc:
|
97
|
+
|
98
|
+
include EnvironmentArgument
|
99
|
+
|
100
|
+
hide_command!
|
101
|
+
|
102
|
+
def perform
|
103
|
+
extract_environment_option
|
104
|
+
|
105
|
+
# CHARYF_ENV needs to be set before application is required.
|
106
|
+
ENV["CHARYF_ENV"] = options[:environment]
|
107
|
+
|
108
|
+
require_application_and_environment!
|
109
|
+
|
110
|
+
Charyf::CLI.start
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'irb'
|
3
|
+
|
4
|
+
require_relative '../../command/base'
|
5
|
+
require_relative '../../command/environment_argument'
|
6
|
+
|
7
|
+
module Charyf
|
8
|
+
|
9
|
+
class Console
|
10
|
+
def self.start(*args)
|
11
|
+
new(*args).start
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :options, :app, :console
|
15
|
+
|
16
|
+
def initialize(app, options = {})
|
17
|
+
@app = app
|
18
|
+
@options = options
|
19
|
+
|
20
|
+
@console = app.config.console || IRB
|
21
|
+
end
|
22
|
+
|
23
|
+
def environment
|
24
|
+
options[:environment]
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :environment?, :environment
|
28
|
+
|
29
|
+
def set_environment!
|
30
|
+
Charyf.env = environment
|
31
|
+
end
|
32
|
+
|
33
|
+
def start
|
34
|
+
set_environment! if environment?
|
35
|
+
|
36
|
+
puts "Loading #{Charyf.env} environment (Charyf #{Charyf.version})"
|
37
|
+
|
38
|
+
console.start
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module Command
|
43
|
+
|
44
|
+
class ConsoleCommand < Base # :nodoc:
|
45
|
+
|
46
|
+
include EnvironmentArgument
|
47
|
+
|
48
|
+
hide_command!
|
49
|
+
|
50
|
+
def initialize(args = [], local_options = {}, config = {})
|
51
|
+
console_options = []
|
52
|
+
|
53
|
+
# For the same behavior as OptionParser, leave only options after "--" in ARGV.
|
54
|
+
termination = local_options.find_index("--")
|
55
|
+
if termination
|
56
|
+
console_options = local_options[termination + 1..-1]
|
57
|
+
local_options = local_options[0...termination]
|
58
|
+
end
|
59
|
+
|
60
|
+
ARGV.replace(console_options)
|
61
|
+
super(args, local_options, config)
|
62
|
+
end
|
63
|
+
|
64
|
+
def perform
|
65
|
+
extract_environment_option
|
66
|
+
|
67
|
+
# CHARYF_ENV needs to be set before application is required.
|
68
|
+
ENV["CHARYF_ENV"] = options[:environment]
|
69
|
+
|
70
|
+
require_application_and_environment!
|
71
|
+
|
72
|
+
Charyf::Console.start(Charyf.application, options)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Charyf
|
4
|
+
module Command
|
5
|
+
class DestroyCommand < Base # :nodoc:
|
6
|
+
no_commands do
|
7
|
+
def help
|
8
|
+
require_application_and_environment!
|
9
|
+
load_generators
|
10
|
+
|
11
|
+
Charyf::Generators.help self.class.command_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def perform(*)
|
16
|
+
generator = args.shift
|
17
|
+
return help unless generator
|
18
|
+
|
19
|
+
require_application_and_environment!
|
20
|
+
load_generators
|
21
|
+
|
22
|
+
Charyf::Generators.invoke generator, args, behavior: :revoke, destination_root: Charyf::Command.root
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command/base'
|
4
|
+
|
5
|
+
module Charyf
|
6
|
+
module Command
|
7
|
+
class GenerateCommand < Base # :nodoc:
|
8
|
+
|
9
|
+
no_commands do
|
10
|
+
def help
|
11
|
+
require_application_and_environment!
|
12
|
+
load_generators
|
13
|
+
|
14
|
+
Charyf::Generators.help self.class.command_name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform(*)
|
19
|
+
generator = args.shift
|
20
|
+
return help unless generator
|
21
|
+
|
22
|
+
require_application_and_environment!
|
23
|
+
load_generators
|
24
|
+
|
25
|
+
ARGV.shift
|
26
|
+
|
27
|
+
Charyf::Generators.invoke generator, args, behavior: :invoke, destination_root: Charyf::Command.root
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
The most common Charyf commands are:
|
2
|
+
console Start the Charyf console (short-cut alias: "c")
|
3
|
+
cli Start the Charyf command line interface. Command line
|
4
|
+
interface allows to chat with charyf application on
|
5
|
+
the base of text messages.
|
6
|
+
|
7
|
+
All commands can be run with -h (or --help) for more information.
|
8
|
+
In addition to those commands, there are:
|
9
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command/base'
|
4
|
+
|
5
|
+
module Charyf
|
6
|
+
module Command
|
7
|
+
class HelpCommand < Base # :nodoc:
|
8
|
+
|
9
|
+
hide_command!
|
10
|
+
desc_file File.expand_path('USAGE', __dir__)
|
11
|
+
|
12
|
+
def help(*)
|
13
|
+
puts self.class.desc
|
14
|
+
|
15
|
+
Charyf::Command.print_commands
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'command'
|
4
|
+
|
5
|
+
aliases = {
|
6
|
+
'c' => 'console',
|
7
|
+
's' => 'server',
|
8
|
+
'g' => 'generate',
|
9
|
+
'd' => 'destroy'
|
10
|
+
}
|
11
|
+
|
12
|
+
command = ARGV.shift
|
13
|
+
command = aliases[command] || command
|
14
|
+
|
15
|
+
Charyf::Command.invoke command, ARGV
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Charyf
|
2
|
+
module Configuration
|
3
|
+
|
4
|
+
class Generators #:nodoc:
|
5
|
+
attr_accessor :options
|
6
|
+
attr_reader :hidden_namespaces
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@hidden_namespaces = []
|
10
|
+
@options = Hash.new { |h, k| h[k] = {} }
|
11
|
+
end
|
12
|
+
|
13
|
+
def hide_namespace(namespace)
|
14
|
+
@hidden_namespaces << namespace
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(method, *args)
|
18
|
+
method = method.to_s.sub(/=$/, "").to_sym
|
19
|
+
|
20
|
+
return @options[method] if args.empty?
|
21
|
+
|
22
|
+
if method == :charyf || args.first.is_a?(Hash)
|
23
|
+
namespace, configuration = method, args.shift
|
24
|
+
else
|
25
|
+
namespace, configuration = args.shift, args.shift
|
26
|
+
namespace = namespace.to_sym if namespace.respond_to?(:to_sym)
|
27
|
+
@options[:charyf][method] = namespace
|
28
|
+
end
|
29
|
+
|
30
|
+
if configuration
|
31
|
+
@options[namespace].merge!(configuration)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Charyf
|
2
|
+
module ErrorHandlers
|
3
|
+
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def<<(handler)
|
7
|
+
handlers << handler
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle_exception(e)
|
11
|
+
Charyf.logger.error "#{e.class}: #{e}".red
|
12
|
+
Charyf.logger.error "\n\tBacktrace: #{e.backtrace.join("\n\t")}"
|
13
|
+
|
14
|
+
handlers.map { |h| h.handle_exception(e) }
|
15
|
+
|
16
|
+
e
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def handlers
|
22
|
+
@handles ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Charyf
|
4
|
+
class Extension
|
5
|
+
module Configurable
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def config
|
13
|
+
instance.config
|
14
|
+
end
|
15
|
+
|
16
|
+
def inherited(base)
|
17
|
+
raise "You cannot inherit from a #{superclass.name} child"
|
18
|
+
end
|
19
|
+
|
20
|
+
def instance
|
21
|
+
@instance ||= new
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(*args)
|
25
|
+
super || instance.respond_to?(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure(&block)
|
29
|
+
class_eval(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def method_missing(*args, &block)
|
35
|
+
instance.send(*args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative '../configuration'
|
3
|
+
|
4
|
+
|
5
|
+
module Charyf
|
6
|
+
class Extension
|
7
|
+
class Configuration
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@@options ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Holds generators configuration:
|
14
|
+
def generators
|
15
|
+
@@generators ||= Charyf::Configuration::Generators.new
|
16
|
+
yield(@generators) if block_given?
|
17
|
+
@@generators
|
18
|
+
end
|
19
|
+
#
|
20
|
+
# # First configurable block to run. Called before any initializers are run.
|
21
|
+
# def before_configuration(&block)
|
22
|
+
# ActiveSupport.on_load(:before_configuration, yield: true, &block)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # Second configurable block to run. Called before frameworks initialize.
|
26
|
+
# def before_initialize(&block)
|
27
|
+
# ActiveSupport.on_load(:before_initialize, yield: true, &block)
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # Last configurable block to run. Called after frameworks initialize.
|
31
|
+
# def after_initialize(&block)
|
32
|
+
# ActiveSupport.on_load(:after_initialize, yield: true, &block)
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # Array of callbacks defined by #to_prepare.
|
36
|
+
# def to_prepare_blocks
|
37
|
+
# @@to_prepare_blocks ||= []
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # Defines generic callbacks to run before #after_initialize. Useful for
|
41
|
+
# # Charyf::Extension subclasses.
|
42
|
+
# def to_prepare(&blk)
|
43
|
+
# to_prepare_blocks << blk if blk
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# def respond_to?(name, include_private = false)
|
47
|
+
# super || @@options.key?(name.to_sym)
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
private
|
51
|
+
|
52
|
+
def method_missing(name, *args, &blk)
|
53
|
+
if name.to_s =~ /=$/
|
54
|
+
@@options[$`.to_sym] = args.first
|
55
|
+
elsif @@options.key?(name)
|
56
|
+
@@options[name]
|
57
|
+
else
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'initializable'
|
4
|
+
require_relative '../support'
|
5
|
+
|
6
|
+
module Charyf
|
7
|
+
class Extension
|
8
|
+
include Initializable
|
9
|
+
|
10
|
+
ABSTRACT = %w(Charyf::Extension Charyf::AppEngine Charyf::Application)
|
11
|
+
|
12
|
+
class << self
|
13
|
+
private :new
|
14
|
+
|
15
|
+
def abstract?
|
16
|
+
ABSTRACT.include?(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def subclasses
|
20
|
+
@subclasses ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
def inherited(base)
|
24
|
+
unless base.abstract?
|
25
|
+
subclasses << base
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def generators(&blk)
|
30
|
+
register_block_for(:generators, &blk)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Since Charyf::Extension cannot be instantiated, any methods that call
|
34
|
+
# +instance+ are intended to be called only on subclasses of a Extension.
|
35
|
+
def instance
|
36
|
+
@instance ||= new
|
37
|
+
end
|
38
|
+
|
39
|
+
def extension_name(name = nil)
|
40
|
+
@extension_name = name.to_s if name
|
41
|
+
@extension_name ||= generate_extension_name(self.name)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def generate_extension_name(string)
|
47
|
+
string.underscore.tr('/', '_')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Allows you to configure the Extension. This is the same method seen in
|
51
|
+
# Extension::Configurable, but this module is no longer required for all
|
52
|
+
# subclasses of Extension so we provide the class method here.
|
53
|
+
def configure(&block)
|
54
|
+
instance.configure(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def config
|
58
|
+
instance.config
|
59
|
+
end
|
60
|
+
|
61
|
+
def respond_to_missing?(name, _)
|
62
|
+
instance.respond_to?(name) || super
|
63
|
+
end
|
64
|
+
|
65
|
+
# If the class method does not have a method, then send the method call
|
66
|
+
# to the Extension instance.
|
67
|
+
def method_missing(name, *args, &block)
|
68
|
+
if instance.respond_to?(name)
|
69
|
+
instance.public_send(name, *args, &block)
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# receives an instance variable identifier, set the variable value if is
|
76
|
+
# blank and append given block to value, which will be used later in
|
77
|
+
# `#each_registered_block(type, &block)`
|
78
|
+
def register_block_for(type, &blk)
|
79
|
+
var_name = "@#{type}"
|
80
|
+
blocks = instance_variable_defined?(var_name) ? instance_variable_get(var_name) : instance_variable_set(var_name, [])
|
81
|
+
blocks << blk if blk
|
82
|
+
blocks
|
83
|
+
end
|
84
|
+
end # End of self
|
85
|
+
|
86
|
+
def initialize #:nodoc:
|
87
|
+
if self.class.abstract?
|
88
|
+
raise "#{self.class.name} is abstract, you cannot instantiate it directly."
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def extension_name(name)
|
93
|
+
self.class.extension_name(name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def configure(&block) #:nodoc:
|
97
|
+
instance_eval(&block)
|
98
|
+
end
|
99
|
+
|
100
|
+
def extension_namespace #:nodoc:
|
101
|
+
@extension_namespace ||= self.class.parents.detect { |n| n.respond_to?(:extension_namespace) }
|
102
|
+
end
|
103
|
+
|
104
|
+
# This is used to create the <tt>config</tt> object on Extensions, an instance of
|
105
|
+
# Extension::Configuration, that is used by Extensions and Application to store
|
106
|
+
# related configuration.
|
107
|
+
def config
|
108
|
+
@config ||= Charyf::Extension::Configuration.new
|
109
|
+
end
|
110
|
+
|
111
|
+
protected
|
112
|
+
|
113
|
+
def run_generators_blocks(app) #:nodoc:
|
114
|
+
each_registered_block(:generators) { |block| block.call(app) }
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# run `&block` in every registered block in `#register_block_for`
|
120
|
+
def each_registered_block(type, &block)
|
121
|
+
klass = self.class
|
122
|
+
while klass.respond_to?(type)
|
123
|
+
klass.public_send(type).each(&block)
|
124
|
+
klass = klass.superclass
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|