vop 0.3.1 → 0.3.4
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 +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