a4tools 1.2.7
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/.bundle/install.log +38 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +38 -0
- data/a4tools.gemspec +38 -0
- data/bin/deploy_latest_clients +32 -0
- data/bin/devsite_config_server +48 -0
- data/bin/netshell +23 -0
- data/bin/update_server +101 -0
- data/bin/usher +54 -0
- data/lib/a4tools.rb +61 -0
- data/lib/a4tools/version.rb +3 -0
- data/lib/acres_client.rb +376 -0
- data/lib/clients/caching_client.rb +151 -0
- data/lib/clients/deployment_client.rb +53 -0
- data/lib/clients/kai_config_client.rb +39 -0
- data/lib/clients/usher_client.rb +72 -0
- data/lib/clients/usher_mgmt_client.rb +201 -0
- data/lib/event_manager.rb +24 -0
- data/lib/events.json +1 -0
- data/lib/net_shell/builtin_command.rb +312 -0
- data/lib/net_shell/builtin_commands/build.rb +251 -0
- data/lib/net_shell/builtin_commands/cd.rb +12 -0
- data/lib/net_shell/builtin_commands/connect.rb +122 -0
- data/lib/net_shell/builtin_commands/deploy.rb +280 -0
- data/lib/net_shell/builtin_commands/disconnect.rb +15 -0
- data/lib/net_shell/builtin_commands/excerpt.rb +97 -0
- data/lib/net_shell/builtin_commands/exit.rb +7 -0
- data/lib/net_shell/builtin_commands/get.rb +38 -0
- data/lib/net_shell/builtin_commands/help.rb +40 -0
- data/lib/net_shell/builtin_commands/host.rb +126 -0
- data/lib/net_shell/builtin_commands/inject.rb +42 -0
- data/lib/net_shell/builtin_commands/jsoncache.rb +80 -0
- data/lib/net_shell/builtin_commands/kai_event.rb +151 -0
- data/lib/net_shell/builtin_commands/persist.rb +24 -0
- data/lib/net_shell/builtin_commands/pwd.rb +6 -0
- data/lib/net_shell/builtin_commands/recap.rb +188 -0
- data/lib/net_shell/builtin_commands/references.rb +63 -0
- data/lib/net_shell/builtin_commands/select.rb +36 -0
- data/lib/net_shell/builtin_commands/send.rb +74 -0
- data/lib/net_shell/builtin_commands/set.rb +29 -0
- data/lib/net_shell/builtin_commands/show.rb +183 -0
- data/lib/net_shell/builtin_commands/site.rb +122 -0
- data/lib/net_shell/builtin_commands/ssh.rb +62 -0
- data/lib/net_shell/builtin_commands/talk.rb +90 -0
- data/lib/net_shell/builtin_commands/translate.rb +45 -0
- data/lib/net_shell/builtin_commands/unset.rb +14 -0
- data/lib/net_shell/builtin_commands/usher.rb +55 -0
- data/lib/net_shell/builtin_commands/usher_device.rb +39 -0
- data/lib/net_shell/builtin_commands/usher_site.rb +245 -0
- data/lib/net_shell/builtin_commands/usherm_connect.rb +21 -0
- data/lib/net_shell/colors.rb +149 -0
- data/lib/net_shell/command.rb +97 -0
- data/lib/net_shell/io.rb +132 -0
- data/lib/net_shell/net_shell.rb +396 -0
- data/lib/net_shell/prompt.rb +335 -0
- data/lib/object_builder/definitions/app_info_for_script.rb +83 -0
- data/lib/object_builder/definitions/connection_request.rb +28 -0
- data/lib/object_builder/definitions/device_info_for_system.rb +37 -0
- data/lib/object_builder/object_builder.rb +145 -0
- data/lib/talk.json +1 -0
- data/lib/talk_consumer.rb +235 -0
- metadata +279 -0
@@ -0,0 +1,335 @@
|
|
1
|
+
require 'curses'
|
2
|
+
Curses.init_screen()
|
3
|
+
|
4
|
+
class String
|
5
|
+
def shellsplit_partial
|
6
|
+
begin
|
7
|
+
shellsplit
|
8
|
+
rescue ArgumentError
|
9
|
+
begin
|
10
|
+
(self + "\"").shellsplit
|
11
|
+
rescue
|
12
|
+
(self + "'").shellsplit rescue []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module A4Tools
|
19
|
+
class Prompt
|
20
|
+
attr_accessor :tab, :prompt, :keystroke, :history, :history_file, :history_length
|
21
|
+
attr_accessor :autosuggest
|
22
|
+
|
23
|
+
def initialize(params={})
|
24
|
+
@history = []
|
25
|
+
@autosuggest = true
|
26
|
+
reset_line
|
27
|
+
|
28
|
+
@prompt = params[:prompt] || lambda { ">" }
|
29
|
+
@tab = params[:tab] || lambda { |cmdline| [] }
|
30
|
+
self.history_file = File.expand_path(params[:history_file]) || nil
|
31
|
+
@history_length = params[:history_length] || 100
|
32
|
+
end
|
33
|
+
|
34
|
+
def quoted_argument(argument)
|
35
|
+
argument.match(/\s+/) ? "\"#{argument}\"" : argument
|
36
|
+
end
|
37
|
+
|
38
|
+
def prompt=(new_prompt)
|
39
|
+
@prompt = new_prompt
|
40
|
+
end
|
41
|
+
|
42
|
+
def prompt
|
43
|
+
@prompt.call() rescue ">"
|
44
|
+
end
|
45
|
+
|
46
|
+
def show_prompt(force_newline=false)
|
47
|
+
puts if force_newline
|
48
|
+
print prompt
|
49
|
+
STDOUT.flush
|
50
|
+
end
|
51
|
+
|
52
|
+
def history_file=(file)
|
53
|
+
@history_file = file
|
54
|
+
@history = IO.read(file).split("\n") if File.exist?(file)
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_to_history(line)
|
58
|
+
return if(history.last == line or line.match(/^\s*$/))
|
59
|
+
@history.push(line)
|
60
|
+
@history = @history[1 .. @history_length] unless @history_length.nil? or @history.length <= @history_length
|
61
|
+
File.write(@history_file, @history.join("\n")) if @history_file
|
62
|
+
end
|
63
|
+
|
64
|
+
def history_at_offset(offset=nil)
|
65
|
+
offset ||= @offset
|
66
|
+
history = (offset == -1) ? @saved_cmd : @history.reverse[offset]
|
67
|
+
history || ""
|
68
|
+
end
|
69
|
+
|
70
|
+
def show_history(offset)
|
71
|
+
print "\r#{prompt}#{history_at_offset(offset)}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def refresh_prompt
|
75
|
+
@last_prompt = prompt
|
76
|
+
end
|
77
|
+
|
78
|
+
def redraw_line
|
79
|
+
clear_line
|
80
|
+
print "#{@last_prompt}#{@line}#{@suggestion.colorize(:light_black)}"
|
81
|
+
print "\b"*(@suggestion.length-@cursor)
|
82
|
+
end
|
83
|
+
|
84
|
+
def clear_line
|
85
|
+
print "\r"
|
86
|
+
print " "*Curses.cols + "\r"
|
87
|
+
end
|
88
|
+
|
89
|
+
def tab_completion(cmdline)
|
90
|
+
if @last_tab.nil?
|
91
|
+
@last_tab = @tab.call(cmdline)
|
92
|
+
end
|
93
|
+
|
94
|
+
@last_tab
|
95
|
+
end
|
96
|
+
|
97
|
+
def common_denominator(set)
|
98
|
+
return "" if set.empty?
|
99
|
+
denom = set[0].to_s
|
100
|
+
set.each do |item|
|
101
|
+
while(not item.to_s.start_with?(denom)) do
|
102
|
+
denom = denom[0..-2]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
denom
|
107
|
+
end
|
108
|
+
|
109
|
+
def read_char
|
110
|
+
STDIN.echo = false
|
111
|
+
|
112
|
+
input = STDIN.getc.chr
|
113
|
+
if input == "\e" then
|
114
|
+
input << STDIN.read_nonblock(4) rescue nil
|
115
|
+
input << STDIN.read_nonblock(3) rescue nil
|
116
|
+
input << STDIN.read_nonblock(2) rescue nil
|
117
|
+
end
|
118
|
+
ensure
|
119
|
+
STDIN.echo = true
|
120
|
+
|
121
|
+
return input
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_argument_from_tab(new_arg, add_space = true)
|
125
|
+
if @line.match(/\s$/) then
|
126
|
+
# Last character is a space; we're adding a brand new argument
|
127
|
+
@line += quoted_argument(new_arg)
|
128
|
+
else
|
129
|
+
# We're completing an existing argument
|
130
|
+
last = split_args.last || ""
|
131
|
+
true_last = split_args(false).last || ""
|
132
|
+
last = "\"" + last if last.match(/\s/) or true_last.start_with? "\""
|
133
|
+
@line = @line[0..(-1 - last.length)] + quoted_argument(new_arg)
|
134
|
+
end
|
135
|
+
|
136
|
+
@line += " " if add_space
|
137
|
+
end
|
138
|
+
|
139
|
+
def handle_ctrl_c
|
140
|
+
puts ""
|
141
|
+
reset_line
|
142
|
+
end
|
143
|
+
|
144
|
+
def handle_ctrl_d
|
145
|
+
exit 0 if @line.length == 0
|
146
|
+
print "\a"
|
147
|
+
end
|
148
|
+
|
149
|
+
def handle_backspace
|
150
|
+
print "\a" if @cursor >= @line.length
|
151
|
+
if @cursor == 0 then
|
152
|
+
@line = @line[0 .. -2] || ""
|
153
|
+
else
|
154
|
+
@line = (@line[0 .. @cursor-2] + @line[@cursor .. -1]) || ""
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def handle_up_arrow
|
159
|
+
if @autosuggest and not at_suggestion_boundary then
|
160
|
+
@suggestion_offset -= 1
|
161
|
+
else
|
162
|
+
print "\a" if @offset == @history.length - 1
|
163
|
+
@saved_cmd = @line if @offset == -1
|
164
|
+
@offset = [@offset + 1, @history.length - 1].min
|
165
|
+
@line = pad_line(history_at_offset)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def handle_down_arrow
|
170
|
+
if @autosuggest and not at_suggestion_boundary then
|
171
|
+
@suggestion_offset += 1
|
172
|
+
else
|
173
|
+
print "\a" if @offset == -1
|
174
|
+
@offset = [@offset - 1, -1].max
|
175
|
+
@line = pad_line(history_at_offset)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def handle_right_arrow
|
180
|
+
if @cursor >= 0 then
|
181
|
+
return unless @autosuggest
|
182
|
+
opts = tab_completion(@line)
|
183
|
+
if opts.empty?
|
184
|
+
print "\a"
|
185
|
+
else
|
186
|
+
suggestion = opts[@suggestion_offset % opts.length]
|
187
|
+
add_argument_from_tab(suggestion) unless suggestion.nil? or suggestion.empty?
|
188
|
+
end
|
189
|
+
else
|
190
|
+
@cursor += 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def handle_left_arrow
|
195
|
+
@cursor = [-@line.length, @cursor - 1].max
|
196
|
+
end
|
197
|
+
|
198
|
+
def handle_newline
|
199
|
+
add_to_history(@line)
|
200
|
+
@suggestion = "" # clear the ghost text off the screen
|
201
|
+
redraw_line
|
202
|
+
puts "\r"
|
203
|
+
end
|
204
|
+
|
205
|
+
def handle_tab
|
206
|
+
opts = tab_completion(@line)
|
207
|
+
forced = common_denominator(opts)
|
208
|
+
add_argument_from_tab(forced, opts.length == 1) unless forced.empty?
|
209
|
+
|
210
|
+
print "\a" if opts.length != 1
|
211
|
+
puts "\r\n"+opts.sort.join(", ") if opts.length > 1
|
212
|
+
end
|
213
|
+
|
214
|
+
def handle_character(c)
|
215
|
+
if @cursor == 0 then
|
216
|
+
@line += c
|
217
|
+
else
|
218
|
+
@line = (@line[0 .. @cursor-1] + c + @line[@cursor .. -1]) || ""
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def handle_home
|
223
|
+
@cursor = -@line.length
|
224
|
+
end
|
225
|
+
|
226
|
+
def handle_end
|
227
|
+
@cursor = 0
|
228
|
+
end
|
229
|
+
|
230
|
+
def handle_pgdown
|
231
|
+
@offset = -1
|
232
|
+
clear_line
|
233
|
+
@line = history_at_offset
|
234
|
+
end
|
235
|
+
|
236
|
+
def split_args(partial=true)
|
237
|
+
partial ? @line.shellsplit_partial : @line.split(/\s+/)
|
238
|
+
end
|
239
|
+
|
240
|
+
def pad_line(line)
|
241
|
+
line += " " unless line.empty? or line.match(/\s$/)
|
242
|
+
line
|
243
|
+
end
|
244
|
+
|
245
|
+
def at_suggestion_boundary
|
246
|
+
return true if @line.length == 0
|
247
|
+
return true if @line.match(/\s$/)
|
248
|
+
false
|
249
|
+
end
|
250
|
+
|
251
|
+
def suggest(str)
|
252
|
+
str ||= ""
|
253
|
+
@suggestion = str.style(:light_black)
|
254
|
+
end
|
255
|
+
|
256
|
+
def update_autosuggest
|
257
|
+
opts = tab_completion(@line)
|
258
|
+
suggested = opts[@suggestion_offset % opts.length] rescue nil
|
259
|
+
if suggested.nil? or at_suggestion_boundary
|
260
|
+
suggest("")
|
261
|
+
return
|
262
|
+
end
|
263
|
+
|
264
|
+
suggested = suggested[ (split_args.last.length rescue 0) .. -1] unless at_suggestion_boundary
|
265
|
+
suggest(suggested) unless suggested.nil?
|
266
|
+
end
|
267
|
+
|
268
|
+
def scan_line
|
269
|
+
c = nil
|
270
|
+
while c != "\r"
|
271
|
+
redraw_line
|
272
|
+
c = read_char
|
273
|
+
|
274
|
+
start_line = @line
|
275
|
+
case c
|
276
|
+
when "\u0003" # CTRL+C
|
277
|
+
handle_ctrl_c
|
278
|
+
when "\u0004" # CTRL+D
|
279
|
+
handle_ctrl_d
|
280
|
+
when "\177" # backspace
|
281
|
+
handle_backspace
|
282
|
+
when "\e[A" # up arrow
|
283
|
+
handle_up_arrow
|
284
|
+
when "\e[B" # down arrow
|
285
|
+
handle_down_arrow
|
286
|
+
when "\e[C" # right arrow
|
287
|
+
handle_right_arrow
|
288
|
+
when "\e[D" # left arrow
|
289
|
+
handle_left_arrow
|
290
|
+
when "\e[H" # home
|
291
|
+
handle_home
|
292
|
+
when "\e[F" # end
|
293
|
+
handle_end
|
294
|
+
when "\e[6~" # page down
|
295
|
+
handle_pgdown
|
296
|
+
when "\r" # newline
|
297
|
+
handle_newline
|
298
|
+
when "\t" # tab
|
299
|
+
handle_tab
|
300
|
+
else
|
301
|
+
handle_character(c) if c.length == 1 # guard against other weird metacharacters
|
302
|
+
end
|
303
|
+
|
304
|
+
@last_tab = nil if start_line != @line # altering the line invalidated tab complete cache
|
305
|
+
@suggestion_offset = 0 if at_suggestion_boundary
|
306
|
+
@keystroke.call(@line) unless @keystroke.nil?
|
307
|
+
update_autosuggest if @autosuggest
|
308
|
+
end
|
309
|
+
|
310
|
+
@line
|
311
|
+
end
|
312
|
+
|
313
|
+
def reset_line
|
314
|
+
@line = ""
|
315
|
+
@suggestion = ""
|
316
|
+
@suggestion_offset = 0
|
317
|
+
@offset = -1
|
318
|
+
@cursor = 0
|
319
|
+
@last_prompt = prompt
|
320
|
+
@last_tab = nil
|
321
|
+
end
|
322
|
+
|
323
|
+
def read_line
|
324
|
+
reset_line
|
325
|
+
begin
|
326
|
+
system("stty raw -echo")
|
327
|
+
scan_line
|
328
|
+
ensure
|
329
|
+
system("stty -raw echo")
|
330
|
+
end
|
331
|
+
|
332
|
+
@line
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'jebediah'
|
2
|
+
|
3
|
+
description "Populated from git and version info"
|
4
|
+
generate do
|
5
|
+
version = get_version.split(".")
|
6
|
+
commits = get_commits
|
7
|
+
|
8
|
+
{
|
9
|
+
__class:"com.acres4.common.info.AppInfo",
|
10
|
+
appName:"netshell",
|
11
|
+
product:"Mercury",
|
12
|
+
|
13
|
+
major: version[0].to_i,
|
14
|
+
minor: version[1].to_i,
|
15
|
+
revision: version[2].to_i,
|
16
|
+
sourceRevision: commits.first[:sha1],
|
17
|
+
buildId: commits.first[:jeb],
|
18
|
+
supportingRevisions: (commits.map do |commit|
|
19
|
+
{
|
20
|
+
repository: commit[:repository],
|
21
|
+
revision: commit[:sha1],
|
22
|
+
alias: commit[:jeb],
|
23
|
+
timestamp: commit[:timestamp],
|
24
|
+
author: commit[:author],
|
25
|
+
commitNotes: commit[:notes],
|
26
|
+
branches: commit[:branches]
|
27
|
+
}
|
28
|
+
end),
|
29
|
+
|
30
|
+
sha1sum:nil,
|
31
|
+
currentTalkVersion:"mike",
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
###
|
36
|
+
|
37
|
+
def repo_info(directory, repository=nil)
|
38
|
+
begin
|
39
|
+
info = {}
|
40
|
+
info[:repository] = repository || File.basename(directory)
|
41
|
+
info[:sha1] = `cd "#{directory}"; git log --format="%H" -n1`.chomp
|
42
|
+
info[:jeb] = Jebediah.new.process(info[:sha1])[:result].join(" ")
|
43
|
+
info[:timestamp] = `cd "#{directory}"; git log --format="%at" -n1`.chomp.to_i
|
44
|
+
info[:author] = `cd "#{directory}"; git log --format="%an" -n1`.chomp
|
45
|
+
info[:notes] = `cd "#{directory}"; git log --format="%s" -n1`.chomp
|
46
|
+
|
47
|
+
info[:branches] = (`cd "#{directory}"; git branch --contains #{info[:sha1]}`.split("\n").map do |line|
|
48
|
+
line.length > 0 ? line.gsub(/^[\s*]*/, "").gsub(/\s*$/, "") : nil
|
49
|
+
end).compact
|
50
|
+
return info
|
51
|
+
rescue
|
52
|
+
return nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def fake_repo_info
|
57
|
+
{
|
58
|
+
repository: "a4tools",
|
59
|
+
sha1:"67021ff1f82c941454a6d2bffa7a2ffde0a6320a",
|
60
|
+
jeb:"exquisitely eased cougar",
|
61
|
+
timestamp:1399271669,
|
62
|
+
author:"Jonas Acres",
|
63
|
+
notes:"Progress commit",
|
64
|
+
branches:["master"]
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_a4tools
|
69
|
+
repo_info(File.dirname(__FILE__), "a4tools")
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_talk
|
73
|
+
repo_info(File.join(File.dirname(__FILE__), "../../../../talk"), "talk")
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_commits
|
77
|
+
#list = [ get_a4tools, get_talk ].compact
|
78
|
+
list = [ fake_repo_info ] if list.nil? or list.empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_version
|
82
|
+
VERSION
|
83
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
description "ConnectionRequest based on default AppInfo and DeviceInfo"
|
2
|
+
cache false
|
3
|
+
generate do
|
4
|
+
{
|
5
|
+
__class:"com.acres4.common.info.ConnectionRequest",
|
6
|
+
appInfo: ObjectBuilder[:app_info_for_script].value,
|
7
|
+
deviceInfo: ObjectBuilder[:device_info_for_system].value,
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
###
|
12
|
+
|
13
|
+
def device_type
|
14
|
+
"Ruby #{RUBY_VERSION}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def serial_number
|
18
|
+
return $config[:serial] unless $config.nil? or $config[:serial].nil?
|
19
|
+
"1234"
|
20
|
+
end
|
21
|
+
|
22
|
+
def hostname
|
23
|
+
`hostname`.chomp
|
24
|
+
end
|
25
|
+
|
26
|
+
def os_name
|
27
|
+
`uname`.chomp
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
description "Populated from local configuration and host info"
|
2
|
+
cache false
|
3
|
+
|
4
|
+
generate do
|
5
|
+
{
|
6
|
+
__class:"com.acres4.common.info.DeviceInfo",
|
7
|
+
identifier:0,
|
8
|
+
serialNumber:serial_number,
|
9
|
+
deviceType:"ruby_script",
|
10
|
+
deviceName:hostname,
|
11
|
+
osName:os_name,
|
12
|
+
osVersion:os_version
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
###
|
17
|
+
|
18
|
+
def device_type
|
19
|
+
"Ruby"
|
20
|
+
end
|
21
|
+
|
22
|
+
def serial_number
|
23
|
+
return $config[:serial] unless $config.nil? or $config[:serial].nil?
|
24
|
+
"1234"
|
25
|
+
end
|
26
|
+
|
27
|
+
def hostname
|
28
|
+
`hostname`.chomp
|
29
|
+
end
|
30
|
+
|
31
|
+
def os_name
|
32
|
+
`uname`.chomp
|
33
|
+
end
|
34
|
+
|
35
|
+
def os_version
|
36
|
+
RUBY_VERSION
|
37
|
+
end
|