vop 0.3.1 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +34 -33
- data/README.md +184 -2
- data/bin/console +17 -0
- data/bin/setup +8 -0
- data/bin/vop.sh +6 -2
- data/exe/vop +3 -25
- data/lib/boot.rb +3 -0
- data/lib/core/meta/commands/new_command.rb +1 -0
- data/lib/core/meta/commands/new_plugin.rb +47 -0
- data/lib/core/meta/commands/search_gems_for_plugins.rb +38 -0
- data/lib/core/meta/commands/search_path.rb +6 -0
- data/lib/core/meta/commands/set.rb +12 -0
- data/lib/core/meta/commands/show.rb +6 -0
- data/lib/core/meta/commands/show_config.rb +9 -0
- data/lib/core/meta/commands/who_provides.rb +6 -0
- data/lib/core/meta/meta.plugin +1 -0
- data/lib/core/shell/commands/change_loglevel.rb +6 -0
- data/lib/{vop/plugins/core → core/shell}/commands/clear_context.rb +0 -0
- data/lib/core/shell/commands/edit.rb +12 -0
- data/lib/core/shell/commands/help.rb +49 -0
- data/lib/core/shell/commands/reset.rb +4 -0
- data/lib/{vop/plugins/core → core/shell}/commands/show_context.rb +0 -0
- data/lib/core/shell/commands/source.rb +21 -0
- data/lib/{vop/plugins/core/helpers/plugin_loader/plugin_syntax.rb → core/shell/shell.plugin} +0 -0
- data/lib/core/structure/commands/collect_contributions.rb +46 -0
- data/lib/core/structure/commands/disable_contributor.rb +16 -0
- data/lib/core/structure/commands/generate_entity_commands.rb +52 -0
- data/lib/core/structure/commands/generate_invalidation_commands.rb +26 -0
- data/lib/core/structure/commands/list_commands.rb +11 -0
- data/lib/core/structure/commands/list_contributors.rb +10 -0
- data/lib/core/structure/commands/list_entities.rb +3 -0
- data/lib/core/structure/commands/list_plugins.rb +3 -0
- data/lib/core/structure/commands/register_contributor.rb +14 -0
- data/lib/core/structure/structure.plugin +4 -0
- data/lib/vop/objects/chain.rb +25 -0
- data/lib/vop/objects/command.rb +86 -0
- data/lib/vop/objects/command_param.rb +39 -0
- data/lib/vop/objects/entities.rb +21 -0
- data/lib/vop/objects/entity.rb +75 -0
- data/lib/vop/objects/entity_definition.rb +33 -0
- data/lib/vop/objects/filter.rb +48 -0
- data/lib/vop/objects/plugin.rb +208 -0
- data/lib/vop/objects/request.rb +73 -0
- data/lib/vop/objects/response.rb +17 -0
- data/lib/vop/objects/thing_with_params.rb +17 -0
- data/lib/vop/{command_loader.rb → parts/command_loader.rb} +8 -12
- data/lib/vop/parts/dependency_resolver.rb +56 -0
- data/lib/vop/parts/entity_loader.rb +46 -0
- data/lib/vop/parts/executor.rb +155 -0
- data/lib/vop/parts/filter_loader.rb +41 -0
- data/lib/vop/parts/plugin_finder.rb +46 -0
- data/lib/vop/parts/plugin_loader.rb +72 -0
- data/lib/vop/shell/shell.rb +221 -0
- data/lib/vop/shell/shell_formatter.rb +110 -0
- data/lib/vop/shell/shell_input.rb +14 -0
- data/lib/vop/shell/shell_input_readline.rb +20 -0
- data/lib/vop/shell/shell_input_testable.rb +27 -0
- data/lib/vop/syntax/command_syntax.rb +90 -0
- data/lib/vop/syntax/entity_syntax.rb +35 -0
- data/lib/vop/syntax/filter_syntax.rb +11 -0
- data/lib/vop/syntax/plugin_syntax.rb +55 -0
- data/lib/vop/util/errors.rb +45 -0
- data/lib/vop/util/pluralizer.rb +26 -0
- data/lib/vop/util/worker.rb +24 -0
- data/lib/vop/version.rb +1 -1
- data/lib/vop/vop.rb +216 -0
- data/lib/vop.rb +16 -229
- data/vop.gemspec +18 -15
- metadata +95 -63
- data/bin/vop.rb +0 -28
- data/lib/vop/command.rb +0 -168
- data/lib/vop/entity.rb +0 -61
- data/lib/vop/loader.rb +0 -35
- data/lib/vop/plugin.rb +0 -141
- data/lib/vop/plugin_loader.rb +0 -88
- data/lib/vop/plugins/core/commands/collect_contributions.rb +0 -31
- data/lib/vop/plugins/core/commands/edit.rb +0 -12
- data/lib/vop/plugins/core/commands/help.rb +0 -38
- data/lib/vop/plugins/core/commands/identity.rb +0 -4
- data/lib/vop/plugins/core/commands/list_contributors.rb +0 -8
- data/lib/vop/plugins/core/commands/list_entities.rb +0 -3
- data/lib/vop/plugins/core/commands/pry.rb +0 -9
- data/lib/vop/plugins/core/commands/reset.rb +0 -5
- data/lib/vop/plugins/core/commands/source.rb +0 -5
- data/lib/vop/plugins/core/commands/system_call.rb +0 -5
- data/lib/vop/plugins/core/core.plugin +0 -4
- data/lib/vop/plugins/core/helpers/command_loader/command_syntax.rb +0 -45
- data/lib/vop/plugins/core/helpers/command_loader/contributions.rb +0 -28
- data/lib/vop/plugins/core/helpers/command_loader/entities.rb +0 -57
- data/lib/vop/plugins/core/helpers/helper.rb +0 -3
- data/lib/vop/plugins/meta/commands/add_search_path.rb +0 -6
- data/lib/vop/plugins/meta/commands/delete_plugin.rb +0 -13
- data/lib/vop/plugins/meta/commands/list_commands.rb +0 -17
- data/lib/vop/plugins/meta/commands/list_plugins.rb +0 -8
- data/lib/vop/plugins/meta/commands/new_command.rb +0 -14
- data/lib/vop/plugins/meta/commands/new_plugin.rb +0 -25
- data/lib/vop/plugins/meta/commands/show_search_path.rb +0 -3
- data/lib/vop/plugins/meta/commands/who_provides.rb +0 -5
- data/lib/vop/plugins/meta/meta.plugin +0 -1
- data/lib/vop/plugins/ssh/commands/scp.rb +0 -11
- data/lib/vop/plugins/ssh/commands/ssh.rb +0 -19
- data/lib/vop/plugins/ssh/ssh.plugin +0 -1
- data/lib/vop/shell/backend.rb +0 -28
- data/lib/vop/shell/base_shell.rb +0 -112
- data/lib/vop/shell/formatter.rb +0 -46
- data/lib/vop/shell/vop_shell_backend.rb +0 -257
- data/lib/vop/shell.rb +0 -52
@@ -0,0 +1,221 @@
|
|
1
|
+
require "readline"
|
2
|
+
require_relative "shell_formatter"
|
3
|
+
require_relative "shell_input"
|
4
|
+
require_relative "shell_input_readline"
|
5
|
+
|
6
|
+
module Vop
|
7
|
+
|
8
|
+
class Shell
|
9
|
+
|
10
|
+
attr_reader :context
|
11
|
+
|
12
|
+
def initialize(op, input = nil)
|
13
|
+
@op = op
|
14
|
+
@context = {}
|
15
|
+
|
16
|
+
@formatter = ShellFormatter.new
|
17
|
+
|
18
|
+
# TODO for testing
|
19
|
+
if input.nil?
|
20
|
+
input = ShellInputReadline.new(method(:tab_completion))
|
21
|
+
end
|
22
|
+
@input = input
|
23
|
+
|
24
|
+
trap('INT') {
|
25
|
+
handle_interrupt
|
26
|
+
}
|
27
|
+
|
28
|
+
reset
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset
|
32
|
+
@command = nil
|
33
|
+
@arguments = {}
|
34
|
+
|
35
|
+
@prompt = if @context.has_key?("prompt")
|
36
|
+
@context["prompt"]
|
37
|
+
else
|
38
|
+
">> "
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def handle_interrupt
|
43
|
+
if @command
|
44
|
+
reset
|
45
|
+
puts
|
46
|
+
print @prompt
|
47
|
+
else
|
48
|
+
puts "\nbye"
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def mix_arguments_and_context
|
54
|
+
result = @arguments
|
55
|
+
@context.each do |k,v|
|
56
|
+
param = @command.param(k)
|
57
|
+
if param && param.wants_context
|
58
|
+
result[k] = @context[k]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def maybe_execute
|
65
|
+
mandatory = @command.mandatory_params
|
66
|
+
|
67
|
+
missing_mandatory_params = @command.mandatory_params.delete_if do |param|
|
68
|
+
@arguments.keys.include?(param.name) ||
|
69
|
+
(@context.keys.include?(param.name) && param.wants_context)
|
70
|
+
end
|
71
|
+
|
72
|
+
$logger.debug "missing params : #{missing_mandatory_params.map(&:name)}"
|
73
|
+
|
74
|
+
if missing_mandatory_params.size > 0
|
75
|
+
@missing_params = missing_mandatory_params
|
76
|
+
@prompt = "#{@command.short_name}.#{@missing_params.first.name} ? "
|
77
|
+
else
|
78
|
+
begin
|
79
|
+
request = Request.new(@op, @command.short_name, @arguments, @context)
|
80
|
+
request.shell = self
|
81
|
+
response = @op.execute_request(request)
|
82
|
+
|
83
|
+
@context.merge! response.context
|
84
|
+
|
85
|
+
display_type = @formatter.analyze(request, response)
|
86
|
+
formatted = @formatter.format(request, response, display_type)
|
87
|
+
puts formatted
|
88
|
+
rescue => detail
|
89
|
+
puts "[ERROR] #{detail.message}\n#{detail.backtrace.join("\n")}"
|
90
|
+
end
|
91
|
+
reset
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def accept_param(line)
|
96
|
+
current_param = @missing_params.shift
|
97
|
+
$logger.debug "value for param #{current_param.name} : #{line}"
|
98
|
+
@arguments[current_param.name] = line
|
99
|
+
|
100
|
+
maybe_execute
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_command_line(args)
|
104
|
+
result = {}
|
105
|
+
unless args.empty?
|
106
|
+
args.each do |token|
|
107
|
+
if token.include? "="
|
108
|
+
(key, value) = token.split("=")
|
109
|
+
result[key] = value
|
110
|
+
else
|
111
|
+
default_param = @command.default_param
|
112
|
+
if default_param
|
113
|
+
result[default_param.name] = args
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
result
|
119
|
+
end
|
120
|
+
|
121
|
+
def parse_and_execute(command_line)
|
122
|
+
(command, *args) = command_line.split
|
123
|
+
|
124
|
+
if command
|
125
|
+
$logger.debug "command : #{command}, args : #{args}"
|
126
|
+
if command.start_with?('$')
|
127
|
+
if command.start_with?('$vop')
|
128
|
+
puts "executing #{command}"
|
129
|
+
puts eval command
|
130
|
+
else
|
131
|
+
puts "unknown $-command #{command} - try '$vop' maybe?"
|
132
|
+
end
|
133
|
+
elsif command.start_with?('@')
|
134
|
+
if command.start_with?('@op')
|
135
|
+
puts "executing #{command}"
|
136
|
+
puts eval command
|
137
|
+
else
|
138
|
+
puts "unknown @-command #{command} - try '@op' maybe?"
|
139
|
+
end
|
140
|
+
else
|
141
|
+
if command.end_with?("?")
|
142
|
+
help_command = command[0..-2]
|
143
|
+
command = "help"
|
144
|
+
args << "name=#{help_command}"
|
145
|
+
end
|
146
|
+
|
147
|
+
if command == "exit"
|
148
|
+
@input.exit
|
149
|
+
else
|
150
|
+
known_commands = @op.commands.keys
|
151
|
+
if known_commands.include? command
|
152
|
+
@command = @op.commands[command]
|
153
|
+
@arguments = parse_command_line(args)
|
154
|
+
|
155
|
+
maybe_execute
|
156
|
+
else
|
157
|
+
puts "unknown command '#{command}'"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
def tab_completion(s)
|
166
|
+
lookups = []
|
167
|
+
|
168
|
+
if @command
|
169
|
+
current_param = @missing_params.first
|
170
|
+
if current_param && current_param.options.has_key?(:lookup)
|
171
|
+
begin
|
172
|
+
lookup_block = current_param.options[:lookup]
|
173
|
+
|
174
|
+
# the lookup block might want the previously collected params as input
|
175
|
+
lookups = if lookup_block.arity > 0
|
176
|
+
params_for_lookup = mix_arguments_and_context
|
177
|
+
lookup_block.call(params_for_lookup)
|
178
|
+
else
|
179
|
+
lookup_block.call()
|
180
|
+
end
|
181
|
+
rescue => detail
|
182
|
+
$logger.error "problem loading lookup values for #{current_param.name} : #{detail.message}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
else
|
186
|
+
lookups = @op.commands.keys.sort
|
187
|
+
end
|
188
|
+
|
189
|
+
lookups.grep /^#{Regexp.escape(s)}/
|
190
|
+
end
|
191
|
+
|
192
|
+
def do_it(command_line = nil)
|
193
|
+
#Readline.completion_append_character = ""
|
194
|
+
#Readline.completion_proc = method(:tab_completion)
|
195
|
+
|
196
|
+
if command_line
|
197
|
+
parse_and_execute(command_line)
|
198
|
+
else
|
199
|
+
while line = @input.read(@prompt)
|
200
|
+
#while line = Readline.readline(@prompt, true)
|
201
|
+
if @command
|
202
|
+
# if a command has already been selected, we ask for missing params
|
203
|
+
accept_param(line)
|
204
|
+
else
|
205
|
+
# otherwise input is treated as regular command line (command + args)
|
206
|
+
parse_and_execute(line)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.run(op = nil, command_line = nil)
|
213
|
+
if op.nil?
|
214
|
+
op = Vop.new
|
215
|
+
end
|
216
|
+
self.new(op).do_it(command_line)
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "terminal-table"
|
2
|
+
|
3
|
+
module Vop
|
4
|
+
|
5
|
+
class ShellFormatter
|
6
|
+
|
7
|
+
def analyze(request, response)
|
8
|
+
data = response.result
|
9
|
+
|
10
|
+
if request.command.show_options[:display_type]
|
11
|
+
# TODO check that display_type is valid
|
12
|
+
request.command.show_options[:display_type]
|
13
|
+
else
|
14
|
+
if data.is_a? Array
|
15
|
+
first_row = data.first
|
16
|
+
if first_row.is_a? Hash
|
17
|
+
:table
|
18
|
+
elsif first_row.is_a? Entity
|
19
|
+
:entity_list
|
20
|
+
else
|
21
|
+
:list
|
22
|
+
end
|
23
|
+
elsif data.is_a? Hash
|
24
|
+
:hash
|
25
|
+
elsif data.is_a? Entity
|
26
|
+
:entity
|
27
|
+
else
|
28
|
+
:raw
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def format(request, response, display_type)
|
34
|
+
data = response.result
|
35
|
+
command = request.command
|
36
|
+
show_options = command.show_options
|
37
|
+
|
38
|
+
result = case display_type
|
39
|
+
when :table
|
40
|
+
columns_to_display =
|
41
|
+
if show_options[:columns]
|
42
|
+
show_options[:columns]
|
43
|
+
else
|
44
|
+
# TODO this is not optimal - what if the second row has more keys than the first?
|
45
|
+
first_row = data.first
|
46
|
+
first_row.keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# add an index column
|
50
|
+
column_headers = [ '#' ] + columns_to_display
|
51
|
+
|
52
|
+
# array of hashes -> array of arrays
|
53
|
+
rearranged = []
|
54
|
+
data.each do |row|
|
55
|
+
values = [ ]
|
56
|
+
columns_to_display.each do |key|
|
57
|
+
values << (row[key.to_s] || row[key.to_sym])
|
58
|
+
end
|
59
|
+
rearranged << values
|
60
|
+
end
|
61
|
+
|
62
|
+
unless show_options.include?(:sort) && show_options[:sort] == false
|
63
|
+
rearranged.sort_by! { |row| row.first || "" }
|
64
|
+
end
|
65
|
+
|
66
|
+
# add the index column after sorting
|
67
|
+
rearranged.each_with_index do |row, index|
|
68
|
+
row.unshift index
|
69
|
+
end
|
70
|
+
|
71
|
+
Terminal::Table.new(
|
72
|
+
rows: rearranged,
|
73
|
+
headings: column_headers
|
74
|
+
)
|
75
|
+
when :list
|
76
|
+
data.join("\n")
|
77
|
+
when :hash
|
78
|
+
data.map do |k,v|
|
79
|
+
"#{k} : #{v}"
|
80
|
+
end.join("\n")
|
81
|
+
when :entity_list
|
82
|
+
data.sort_by { |e| e.id }.map do |entity|
|
83
|
+
attributes = entity.data.sort_by do |x|
|
84
|
+
|
85
|
+
end.map do |key, value|
|
86
|
+
if key == entity.key
|
87
|
+
nil
|
88
|
+
else
|
89
|
+
"#{key} : #{value}"
|
90
|
+
end
|
91
|
+
end.compact.join("\n ")
|
92
|
+
"[#{entity.type}] #{entity.id}\n #{attributes}"
|
93
|
+
end.join("\n")
|
94
|
+
when :entity
|
95
|
+
entity = data
|
96
|
+
"[#{entity.type}] #{entity.id}"
|
97
|
+
when :raw
|
98
|
+
data
|
99
|
+
when :data
|
100
|
+
data.pretty_inspect
|
101
|
+
else
|
102
|
+
raise "unknown display type #{display_type}"
|
103
|
+
end
|
104
|
+
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
class ShellInputReadline
|
4
|
+
|
5
|
+
def initialize(completion_method)
|
6
|
+
Readline.completion_append_character = ""
|
7
|
+
Readline.completion_proc = completion_method
|
8
|
+
end
|
9
|
+
|
10
|
+
def read(prompt)
|
11
|
+
Readline.readline(prompt, true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def exit
|
15
|
+
Kernel.exit
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
class TestableShellInput
|
4
|
+
|
5
|
+
attr_accessor :answers
|
6
|
+
attr_reader :exit
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@answers = []
|
10
|
+
@exit = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(prompt)
|
14
|
+
answer = @answers.shift
|
15
|
+
if answer.nil?
|
16
|
+
raise "no more pre-defined answers (asked for '#{prompt}')"
|
17
|
+
end
|
18
|
+
answer
|
19
|
+
end
|
20
|
+
|
21
|
+
def exit
|
22
|
+
@exit = true
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
module CommandSyntax
|
4
|
+
|
5
|
+
def run(&block)
|
6
|
+
@command.block = block
|
7
|
+
end
|
8
|
+
|
9
|
+
def description(s)
|
10
|
+
@command.description = s
|
11
|
+
end
|
12
|
+
|
13
|
+
def resolve_options_string(options)
|
14
|
+
if options.is_a? String
|
15
|
+
options = {
|
16
|
+
description: options
|
17
|
+
}
|
18
|
+
end
|
19
|
+
options
|
20
|
+
end
|
21
|
+
|
22
|
+
def param(name, options = {})
|
23
|
+
if name.is_a? Symbol
|
24
|
+
key = "name" # default for select_machine
|
25
|
+
entity = @op.entities.values.select { |x| x.short_name == name.to_s }.first
|
26
|
+
if entity.nil?
|
27
|
+
raise "entity #{name.to_s} defined as param in #{@command.name} not found"
|
28
|
+
else
|
29
|
+
key = entity.key
|
30
|
+
end
|
31
|
+
|
32
|
+
options[:entity] = true
|
33
|
+
options[:lookup] = lambda do
|
34
|
+
list_command_name = name.to_s.carefully_pluralize
|
35
|
+
the_list = @op.execute(list_command_name, {})
|
36
|
+
the_list.map(&key.to_sym)
|
37
|
+
end
|
38
|
+
name = name.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
options = resolve_options_string(options)
|
42
|
+
|
43
|
+
@command.add_param(name, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def param!(name, options = {})
|
47
|
+
options = resolve_options_string(options)
|
48
|
+
options.merge! mandatory: true
|
49
|
+
param(name, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# TODO does not really work yet
|
53
|
+
def block_param(name = "block", options = {})
|
54
|
+
options.merge! block: true
|
55
|
+
param(name, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def block_param!(name = "block", options = {})
|
59
|
+
options = resolve_options_string(options)
|
60
|
+
options.merge! mandatory: true
|
61
|
+
block_param(name, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def read_only
|
65
|
+
@command.read_only = true
|
66
|
+
end
|
67
|
+
|
68
|
+
def allows_extra
|
69
|
+
@command.allows_extra = true
|
70
|
+
end
|
71
|
+
|
72
|
+
def show(options = {})
|
73
|
+
@command.show_options[:columns] = options.delete(:columns)
|
74
|
+
@command.show_options[:display_type] = options.delete(:display_type)
|
75
|
+
@command.show_options[:sort] = options.delete(:sort)
|
76
|
+
|
77
|
+
raise "unknown keyword #{options.keys.first}" if options.keys.length > 0
|
78
|
+
end
|
79
|
+
|
80
|
+
def contribute(options, &block)
|
81
|
+
@op.register_contributor(
|
82
|
+
command_name: options[:to] || @command.short_name,
|
83
|
+
contributor: @command.name
|
84
|
+
)
|
85
|
+
@command.block = block
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
module EntitySyntax
|
4
|
+
|
5
|
+
def key(key)
|
6
|
+
@entity.key = key
|
7
|
+
end
|
8
|
+
|
9
|
+
def entity(options = { key: "name" }, &block)
|
10
|
+
if block
|
11
|
+
run(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(&block)
|
16
|
+
@entity.block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def on(other_entity)
|
20
|
+
@entity.on = other_entity
|
21
|
+
end
|
22
|
+
|
23
|
+
def show(options = {})
|
24
|
+
column_options = options.delete(:columns)
|
25
|
+
display_type = options.delete(:display_type)
|
26
|
+
|
27
|
+
raise "unknown keyword #{options.keys.first}" if options.keys.length > 0
|
28
|
+
|
29
|
+
@entity.show_options[:columns] = column_options
|
30
|
+
@entity.show_options[:display_type] = display_type
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
module PluginSyntax
|
4
|
+
|
5
|
+
def resolve_options_string(options)
|
6
|
+
if options.is_a? String
|
7
|
+
options = {
|
8
|
+
description: options
|
9
|
+
}
|
10
|
+
end
|
11
|
+
options
|
12
|
+
end
|
13
|
+
|
14
|
+
def config_param(name, options = {})
|
15
|
+
options = resolve_options_string(options)
|
16
|
+
|
17
|
+
@plugin.params << CommandParam.new(name, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def config_param!(name, options = {})
|
21
|
+
options = resolve_options_string(options)
|
22
|
+
options.merge! mandatory: true
|
23
|
+
config_param(name, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
def description(string)
|
29
|
+
@plugin.description = string
|
30
|
+
end
|
31
|
+
|
32
|
+
def auto_load(bool)
|
33
|
+
@plugin.options[:auto_load] = bool
|
34
|
+
end
|
35
|
+
|
36
|
+
def depends_on(others)
|
37
|
+
others = [ others ] unless others.is_a?(Array)
|
38
|
+
|
39
|
+
others.each do |other|
|
40
|
+
$logger.debug "plugin #{@plugin.name} depends on #{other}"
|
41
|
+
@plugin.dependencies << other.to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def on(hook_sym, &block)
|
46
|
+
@plugin.hook(hook_sym, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def hook(hook_sym, &block)
|
50
|
+
@op.hook(hook_sym, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Vop
|
2
|
+
|
3
|
+
module Errors
|
4
|
+
|
5
|
+
class RunningInCircles < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class MissingPlugin < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
# see http://www.virtuouscode.com/2013/12/25/exception-causes-in-ruby-2-1/
|
12
|
+
class NestedError < StandardError
|
13
|
+
|
14
|
+
def initialize(message, original = $!)
|
15
|
+
super(message + " : " + original.message)
|
16
|
+
set_backtrace(original.backtrace)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class CommandLoadError < NestedError
|
22
|
+
end
|
23
|
+
|
24
|
+
class PluginLoadError < StandardError
|
25
|
+
end
|
26
|
+
|
27
|
+
class EntityLoadError < LoadError
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class LoadError < StandardError
|
32
|
+
|
33
|
+
attr_reader :message, :detail
|
34
|
+
|
35
|
+
def initialize(message = nil, detail = nil)
|
36
|
+
@message = message
|
37
|
+
@detail = detail
|
38
|
+
super(detail)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require "active_support/inflector"
|
3
|
+
rescue Exception => e
|
4
|
+
message = "active_support inflector cannot be loaded - pluralization results may deviate : #{e.message}"
|
5
|
+
puts message
|
6
|
+
end
|
7
|
+
|
8
|
+
module Vop
|
9
|
+
|
10
|
+
module Pluralizer
|
11
|
+
|
12
|
+
class ::String
|
13
|
+
|
14
|
+
def carefully_pluralize
|
15
|
+
begin
|
16
|
+
self.pluralize(2)
|
17
|
+
rescue
|
18
|
+
"#{self}s"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "sidekiq"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Vop
|
5
|
+
|
6
|
+
class AsyncExecutorWorker
|
7
|
+
include Sidekiq::Worker
|
8
|
+
|
9
|
+
def perform(request_json)
|
10
|
+
begin
|
11
|
+
op = ::Vop.boot
|
12
|
+
request = ::Vop::Request::from_json(op, request_json)
|
13
|
+
puts "performing #{request.pretty_inspect}"
|
14
|
+
response = op.execute_request(request)
|
15
|
+
puts "response : #{response.status}"
|
16
|
+
puts response.result
|
17
|
+
rescue => e
|
18
|
+
puts "[ERROR] #{e.message}\n#{e.backtrace.join("\n")}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/vop/version.rb
CHANGED