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.
- 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,131 @@
|
|
|
1
|
+
require_relative 'configuration'
|
|
2
|
+
|
|
3
|
+
require_relative 'application/configuration'
|
|
4
|
+
require_relative 'application/bootstrap'
|
|
5
|
+
|
|
6
|
+
require_relative 'app_engine'
|
|
7
|
+
require_relative 'utils'
|
|
8
|
+
|
|
9
|
+
require_relative '../support'
|
|
10
|
+
|
|
11
|
+
module Charyf
|
|
12
|
+
class Application < AppEngine
|
|
13
|
+
|
|
14
|
+
include Charyf::Initializable
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
attr_accessor :called_from
|
|
18
|
+
|
|
19
|
+
def inherited(base)
|
|
20
|
+
super
|
|
21
|
+
Charyf.app_class = base
|
|
22
|
+
|
|
23
|
+
base.called_from = begin
|
|
24
|
+
call_stack = caller_locations.map { |l| l.absolute_path || l.path }
|
|
25
|
+
|
|
26
|
+
File.dirname(call_stack.detect { |p| p !~ %r[charyf[\w.-]*/lib/utils] })
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def instance
|
|
31
|
+
super.run_load_hooks!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def find_root(from)
|
|
35
|
+
Charyf::Utils.find_root_with_flag 'config/chapp.rb', from
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def config
|
|
39
|
+
instance.config
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def initialize!(group: :default)
|
|
45
|
+
return self if @initialized
|
|
46
|
+
@initialized = true
|
|
47
|
+
|
|
48
|
+
run_initializers(group, self)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def run_load_hooks!
|
|
52
|
+
return self if @ran_load_hooks
|
|
53
|
+
@ran_load_hooks = true
|
|
54
|
+
|
|
55
|
+
# Todo LOAD Hooks should be here
|
|
56
|
+
self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def config
|
|
60
|
+
@config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def configure(&block)
|
|
64
|
+
instance_eval(&block)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# TODO sig, nullable
|
|
68
|
+
def session_processor
|
|
69
|
+
# TODO resolve dependency on engine - maybe move the base classes to utils?
|
|
70
|
+
klass = Charyf::Engine::Session::Processor.list[config.session_processor]
|
|
71
|
+
raise Charyf::Utils::InvalidConfiguration.new("No storage processor strategy with name '#{config.session_processor}' found") unless klass
|
|
72
|
+
|
|
73
|
+
klass
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def intent_processors
|
|
77
|
+
# TODO resolve dependency on engine - maybe move the base classes to utils?
|
|
78
|
+
klasses = config.enabled_intent_processors.map do |processor_name|
|
|
79
|
+
klass = Charyf::Engine::Intent::Processor.list[processor_name]
|
|
80
|
+
raise Charyf::Utils::InvalidConfiguration.new("No intent processor strategy with name '#{processor_name}' found") unless klass
|
|
81
|
+
|
|
82
|
+
klass
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
raise Charyf::Utils::InvalidConfiguration.new('No intent processor strategies specified') if klasses.empty?
|
|
86
|
+
|
|
87
|
+
klasses
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def dispatcher
|
|
91
|
+
# TODO resolve dependency on engine - maybe move the base classes to utils?
|
|
92
|
+
klass = Charyf::Engine::Dispatcher.list[config.dispatcher]
|
|
93
|
+
raise Charyf::Utils::InvalidConfiguration.new("No dispatcher with name '#{config.dispatcher}' found") unless klass
|
|
94
|
+
|
|
95
|
+
klass
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# TODO sig, nullable
|
|
99
|
+
def storage_provider
|
|
100
|
+
klass = Charyf::Utils::StorageProvider.list[config.storage_provider]
|
|
101
|
+
raise Charyf::Utils::InvalidConfiguration.new("No storage provider with name '#{config.storage_provider}' found") unless klass
|
|
102
|
+
|
|
103
|
+
klass
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def parser
|
|
107
|
+
klass = Charyf::Utils::Parser.get(config.i18n.locale)
|
|
108
|
+
raise Charyf::Utils::InvalidConfiguration.new("No parser for locale '#{config.i18n.locale}' found") unless klass
|
|
109
|
+
|
|
110
|
+
klass
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
protected
|
|
114
|
+
|
|
115
|
+
def run_generators_blocks(app) #:nodoc:
|
|
116
|
+
extensions.each { |r| r.run_generators_blocks(app) }
|
|
117
|
+
super
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def initializers
|
|
121
|
+
Bootstrap.initializers_for(self)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def extensions
|
|
127
|
+
@extensions ||= Extensions.new
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
module Charyf
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
@application = @app_class = nil
|
|
7
|
+
|
|
8
|
+
attr_accessor :app_class
|
|
9
|
+
|
|
10
|
+
def application
|
|
11
|
+
@application ||= (@app_class.instance if app_class)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def configuration
|
|
15
|
+
application.config
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def root
|
|
19
|
+
application && application.config.root
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def env
|
|
23
|
+
@_env ||= Charyf::StringInquirer.new(ENV["CHARYF_ENV"] || "development")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def env=(environment)
|
|
27
|
+
@_env = Charyf::StringInquirer.new(environment)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def logger
|
|
31
|
+
return @logger if @logger
|
|
32
|
+
|
|
33
|
+
FileUtils.mkdir_p root.join('log')
|
|
34
|
+
@logger = Charyf::Logger.new(Charyf.root.join('log', "#{env}.log"))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def groups(*groups)
|
|
38
|
+
# TODO
|
|
39
|
+
[:default, env]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'app_loader'
|
|
4
|
+
|
|
5
|
+
# If we are inside a Charyf application this method performs an exec and thus
|
|
6
|
+
# the rest of this script is not run.
|
|
7
|
+
Charyf::AppLoader.exec_app
|
|
8
|
+
|
|
9
|
+
require_relative 'ruby_version_check'
|
|
10
|
+
Signal.trap("INT") { puts; exit(1) }
|
|
11
|
+
|
|
12
|
+
require_relative 'command'
|
|
13
|
+
|
|
14
|
+
Charyf::Command.invoke :application, ARGV
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Charyf
|
|
4
|
+
module Command
|
|
5
|
+
module Actions
|
|
6
|
+
|
|
7
|
+
# def set_application_directory!
|
|
8
|
+
# Dir.chdir(File.expand_path("../..", APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
|
|
9
|
+
# end
|
|
10
|
+
|
|
11
|
+
def require_application_and_environment!
|
|
12
|
+
if defined?(APP_PATH)
|
|
13
|
+
require APP_PATH
|
|
14
|
+
Charyf.application.initialize!
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def load_generators
|
|
19
|
+
Charyf.application.load_generators
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
require 'erb'
|
|
5
|
+
|
|
6
|
+
require_relative 'actions'
|
|
7
|
+
|
|
8
|
+
module Charyf
|
|
9
|
+
module Command
|
|
10
|
+
class Base < Thor
|
|
11
|
+
class Error < Thor::Error # :nodoc:
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
include Actions
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
|
|
18
|
+
# Tries to get the description from a USAGE file one folder above the command
|
|
19
|
+
# root.
|
|
20
|
+
def desc(usage = nil, description = nil, options = {})
|
|
21
|
+
if usage
|
|
22
|
+
super
|
|
23
|
+
else
|
|
24
|
+
@desc ||= ERB.new(File.read(desc_file)).result(binding) if desc_file
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def desc_file(desc_file = nil)
|
|
29
|
+
@desc_file = desc_file if desc_file
|
|
30
|
+
|
|
31
|
+
@desc_file if @desc_file && File.exist?(@desc_file)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Convenience method to get the namespace from the class name. It's the
|
|
35
|
+
# same as Thor default except that the Command at the end of the class
|
|
36
|
+
# is removed.
|
|
37
|
+
def namespace(name = nil)
|
|
38
|
+
if name
|
|
39
|
+
super
|
|
40
|
+
else
|
|
41
|
+
@namespace ||= super.chomp("_command").sub(/:command:/, ":")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Convenience method to hide this command from the available ones when
|
|
46
|
+
# running charyf help command.
|
|
47
|
+
def hide_command!
|
|
48
|
+
Charyf::Command.hidden_commands << self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def inherited(base) #:nodoc:
|
|
52
|
+
super
|
|
53
|
+
|
|
54
|
+
if base.name && base.name !~ /Base$/
|
|
55
|
+
Charyf::Command.subclasses << base
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def perform(command, args, config) # :nodoc:
|
|
60
|
+
if Charyf::Command::HELP_MAPPINGS.include?(args.first)
|
|
61
|
+
command, args = "help", []
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
dispatch(command, args.dup, nil, config)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def printing_commands
|
|
68
|
+
namespaced_commands
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def executable
|
|
72
|
+
"bin/charyf #{command_name}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def banner(*)
|
|
76
|
+
"#{executable} #{arguments.map(&:usage).join(' ')} [options]".squish
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Sets the base_name taking into account the current class namespace.
|
|
80
|
+
#
|
|
81
|
+
# Charyf::Command::TestCommand.base_name # => 'charyf'
|
|
82
|
+
def base_name
|
|
83
|
+
@base_name ||= begin
|
|
84
|
+
if base = name.to_s.split("::").first
|
|
85
|
+
base.underscore
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Return command name without namespaces.
|
|
91
|
+
#
|
|
92
|
+
# Charyf::Command::TestCommand.command_name # => 'test'
|
|
93
|
+
def command_name
|
|
94
|
+
@command_name ||= begin
|
|
95
|
+
if command = name.to_s.split("::").last
|
|
96
|
+
command.chomp!("Command")
|
|
97
|
+
command.underscore
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private
|
|
103
|
+
# Allow the command method to be called perform.
|
|
104
|
+
def create_command(meth)
|
|
105
|
+
if meth == "perform"
|
|
106
|
+
alias_method command_name, meth
|
|
107
|
+
else
|
|
108
|
+
# Prevent exception about command without usage.
|
|
109
|
+
# Some commands define their documentation differently.
|
|
110
|
+
@usage ||= ""
|
|
111
|
+
@desc ||= ""
|
|
112
|
+
|
|
113
|
+
super
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def command_root_namespace
|
|
118
|
+
(namespace.split(":") - %w( charyf )).first
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def namespaced_commands
|
|
122
|
+
commands.keys.map do |key|
|
|
123
|
+
key == command_root_namespace ? key : "#{command_root_namespace}:#{key}"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def help
|
|
129
|
+
if command_name = self.class.command_name
|
|
130
|
+
self.class.command_help(shell, command_name)
|
|
131
|
+
else
|
|
132
|
+
super
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative '../../support'
|
|
3
|
+
|
|
4
|
+
module Charyf
|
|
5
|
+
module Command
|
|
6
|
+
module Behavior #:nodoc:
|
|
7
|
+
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.extend(ClassMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
|
|
14
|
+
# Track all subclasses.
|
|
15
|
+
def subclasses
|
|
16
|
+
@subclasses ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Remove the color from output.
|
|
20
|
+
def no_color!
|
|
21
|
+
Thor::Base.shell = Thor::Shell::Basic
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# This code is based dir
|
|
27
|
+
# Prints a list of generators.
|
|
28
|
+
def print_list(base, namespaces)
|
|
29
|
+
return if namespaces.nil? ||namespaces.empty?
|
|
30
|
+
puts "#{base.camelize}:"
|
|
31
|
+
|
|
32
|
+
namespaces.each do |namespace|
|
|
33
|
+
puts(" #{namespace}")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
puts
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# This code is based directly on the Text gem implementation.
|
|
40
|
+
# Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
|
|
41
|
+
#
|
|
42
|
+
# Returns a value representing the "cost" of transforming str1 into str2.
|
|
43
|
+
def levenshtein_distance(str1, str2) # :doc:
|
|
44
|
+
s = str1
|
|
45
|
+
t = str2
|
|
46
|
+
n = s.length
|
|
47
|
+
m = t.length
|
|
48
|
+
|
|
49
|
+
return m if (0 == n)
|
|
50
|
+
return n if (0 == m)
|
|
51
|
+
|
|
52
|
+
d = (0..m).to_a
|
|
53
|
+
x = nil
|
|
54
|
+
|
|
55
|
+
# avoid duplicating an enumerable object in the loop
|
|
56
|
+
str2_codepoint_enumerable = str2.each_codepoint
|
|
57
|
+
|
|
58
|
+
str1.each_codepoint.with_index do |char1, i|
|
|
59
|
+
e = i + 1
|
|
60
|
+
|
|
61
|
+
str2_codepoint_enumerable.with_index do |char2, j|
|
|
62
|
+
cost = (char1 == char2) ? 0 : 1
|
|
63
|
+
x = [
|
|
64
|
+
d[j + 1] + 1, # insertion
|
|
65
|
+
e + 1, # deletion
|
|
66
|
+
d[j] + cost # substitution
|
|
67
|
+
].min
|
|
68
|
+
d[j] = e
|
|
69
|
+
e = x
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
d[m] = x
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
x
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Charyf
|
|
4
|
+
module Command
|
|
5
|
+
module EnvironmentArgument #:nodoc:
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.class_option :environment, aliases: "-e", type: :string,
|
|
10
|
+
desc: "Specifies the environment to run this console under (test/development/production)."
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
def extract_environment_option
|
|
15
|
+
if options[:environment]
|
|
16
|
+
self.options = options.merge(environment: acceptable_environment(options[:environment]))
|
|
17
|
+
else
|
|
18
|
+
self.options = options.merge(environment: Charyf::Command.environment)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def acceptable_environment(env = nil)
|
|
23
|
+
if available_environments.include? env
|
|
24
|
+
env
|
|
25
|
+
else
|
|
26
|
+
%w( production development test ).detect { |e| e =~ /^#{env}/ } || env
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def available_environments
|
|
31
|
+
if Object.const_defined? 'APP_PATH'
|
|
32
|
+
app_path = File.expand_path("..", APP_PATH)
|
|
33
|
+
return Dir[app_path + "/environments/*.rb"].map { |fname| File.basename(fname, ".*") }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
[]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require_relative '../support/object'
|
|
2
|
+
require_relative 'command/base'
|
|
3
|
+
require_relative 'command/behavior'
|
|
4
|
+
|
|
5
|
+
module Charyf
|
|
6
|
+
module Command
|
|
7
|
+
|
|
8
|
+
HELP_MAPPINGS = %w(-h -? --help)
|
|
9
|
+
|
|
10
|
+
include Behavior
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
|
|
14
|
+
def environment # :nodoc:
|
|
15
|
+
ENV['CHARYF_ENV'] ? ENV['CHARYF_ENV'] : 'development'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def hidden_commands # :nodoc:
|
|
19
|
+
@hidden_commands ||= []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load_commands!
|
|
23
|
+
require_relative 'commands/all'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Receives a namespace, arguments and the behavior to invoke the command.
|
|
27
|
+
def invoke(full_namespace, args = [], **config)
|
|
28
|
+
load_commands!
|
|
29
|
+
|
|
30
|
+
namespace = full_namespace = full_namespace.to_s
|
|
31
|
+
|
|
32
|
+
if char = namespace =~ /:(\w+)$/
|
|
33
|
+
command_name, namespace = $1, namespace.slice(0, char)
|
|
34
|
+
else
|
|
35
|
+
command_name = namespace
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
command_name, namespace = "help", "help" if command_name.blank? || HELP_MAPPINGS.include?(command_name)
|
|
39
|
+
command_name, namespace = "version", "version" if %w( -v --version ).include?(command_name)
|
|
40
|
+
|
|
41
|
+
command = find_by_namespace(namespace, command_name)
|
|
42
|
+
|
|
43
|
+
# if command && command.all_commands[command_name]
|
|
44
|
+
if command
|
|
45
|
+
command.perform(command_name, args, config)
|
|
46
|
+
else
|
|
47
|
+
$stderr.puts "Unknown command #{full_namespace}\n\n"
|
|
48
|
+
command_name, namespace = "help", "help"
|
|
49
|
+
command = find_by_namespace(namespace, command_name)
|
|
50
|
+
command.perform(command_name, args, config)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# else
|
|
54
|
+
# find_by_namespace("rake").perform(full_namespace, args, config)
|
|
55
|
+
# end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def find_by_namespace(namespace, command_name = nil) # :nodoc:
|
|
59
|
+
lookups = [namespace]
|
|
60
|
+
lookups << "#{namespace}:#{command_name}" if command_name
|
|
61
|
+
lookups.concat lookups.map {|lookup| "charyf:#{lookup}"}
|
|
62
|
+
|
|
63
|
+
namespaces = subclasses.inject(Hash.new) {|h, n| h[n.namespace] = n; h}
|
|
64
|
+
namespaces[(lookups & namespaces.keys).first]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def print_commands # :nodoc:
|
|
68
|
+
sorted_groups.each {|b, n| print_list(b, n)}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def sorted_groups # :nodoc:
|
|
72
|
+
groups = (subclasses - hidden_commands).group_by {|c| c.namespace.split(":").first}
|
|
73
|
+
|
|
74
|
+
groups.keys.each do |key|
|
|
75
|
+
groups[key] = groups[key].flat_map(&:printing_commands).sort
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
charyf = groups.delete('charyf')
|
|
79
|
+
[['charyf', charyf]] + groups.sort.to_a
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns the root of the Charyf engine or app running the command.
|
|
83
|
+
def root
|
|
84
|
+
if defined?(APP_PATH)
|
|
85
|
+
Pathname.new(File.expand_path("../..", APP_PATH))
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def command_type # :doc:
|
|
92
|
+
@command_type ||= "command"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def lookup_paths # :doc:
|
|
96
|
+
@lookup_paths ||= %w( charyf/commands commands charyf/commands )
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def file_lookup_paths # :doc:
|
|
100
|
+
@file_lookup_paths ||= ["{#{lookup_paths.join(',')}}", "**", "*_command.rb"]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end # End of self
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../generators'
|
|
4
|
+
require_relative '../../generators/app/app_generator'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Command
|
|
8
|
+
class ApplicationCommand < Base # :nodoc:
|
|
9
|
+
hide_command!
|
|
10
|
+
|
|
11
|
+
def help
|
|
12
|
+
perform # Punt help output to the generator.
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def perform(*args)
|
|
16
|
+
Charyf::Generators::AppGenerator.start \
|
|
17
|
+
Charyf::Generators::ARGVScrubber.new(args).prepare!
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|