odysseus-cli 0.3.0 → 0.10.0
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/CHANGELOG.md +334 -0
- data/LICENSE.txt +26 -0
- data/README.md +472 -88
- data/bin/odysseus +176 -118
- data/lib/odysseus/cli/cli.rb +293 -229
- data/lib/odysseus/cli/doctor_commands.rb +93 -0
- data/lib/odysseus/cli/interactive_commands.rb +198 -0
- data/lib/odysseus/cli/rollback_commands.rb +107 -0
- data/lib/odysseus/cli/setup_commands.rb +176 -0
- data/lib/odysseus/cli/ui.rb +49 -39
- data/lib/odysseus/cli/version.rb +7 -0
- metadata +18 -49
data/lib/odysseus/cli/ui.rb
CHANGED
|
@@ -35,8 +35,8 @@ module Odysseus
|
|
|
35
35
|
@io.respond_to?(method, include_private)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def method_missing(method,
|
|
39
|
-
@io.send(method,
|
|
38
|
+
def method_missing(method, *, &)
|
|
39
|
+
@io.send(method, *, &)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -68,27 +68,32 @@ module Odysseus
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# --- Header ---
|
|
71
|
+
#
|
|
72
|
+
# These three take `io` for the same reason error/warn/step below do: the
|
|
73
|
+
# interactive sessions print a header describing a terminal whose own
|
|
74
|
+
# output is stdout, so the description has to go somewhere else. The
|
|
75
|
+
# default keeps every other caller writing exactly where it did.
|
|
71
76
|
|
|
72
|
-
def header(title)
|
|
77
|
+
def header(title, io: $stdout)
|
|
73
78
|
reset_steps!
|
|
74
79
|
if debug?
|
|
75
|
-
puts "\e[36m#{title}\e[0m"
|
|
80
|
+
io.puts "\e[36m#{title}\e[0m"
|
|
76
81
|
else
|
|
77
|
-
puts
|
|
78
|
-
puts " #{COPPER}#{title}#{RESET}"
|
|
82
|
+
io.puts ''
|
|
83
|
+
io.puts " #{COPPER}#{title}#{RESET}"
|
|
79
84
|
end
|
|
80
85
|
end
|
|
81
86
|
|
|
82
|
-
def info(label, value)
|
|
87
|
+
def info(label, value, io: $stdout)
|
|
83
88
|
if debug?
|
|
84
|
-
puts " #{label}: #{value}"
|
|
89
|
+
io.puts " #{label}: #{value}"
|
|
85
90
|
else
|
|
86
|
-
puts " #{DIM}#{label}:#{RESET} #{value}"
|
|
91
|
+
io.puts " #{DIM}#{label}:#{RESET} #{value}"
|
|
87
92
|
end
|
|
88
93
|
end
|
|
89
94
|
|
|
90
|
-
def blank
|
|
91
|
-
puts
|
|
95
|
+
def blank(io: $stdout)
|
|
96
|
+
io.puts ''
|
|
92
97
|
end
|
|
93
98
|
|
|
94
99
|
# --- Single spin step ---
|
|
@@ -116,19 +121,18 @@ module Odysseus
|
|
|
116
121
|
$stdout = wr
|
|
117
122
|
|
|
118
123
|
thread = Thread.new do
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
wr.close
|
|
126
|
-
end
|
|
124
|
+
result = yield
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
err = e
|
|
127
|
+
ensure
|
|
128
|
+
done = true
|
|
129
|
+
wr.close
|
|
127
130
|
end
|
|
128
131
|
|
|
129
132
|
frame_idx = 0
|
|
130
133
|
loop do
|
|
131
134
|
break if done
|
|
135
|
+
|
|
132
136
|
frame = SPINNER_FRAMES[frame_idx % SPINNER_FRAMES.size]
|
|
133
137
|
old_stdout.print "\r #{DIM}#{num}#{RESET} #{COPPER}#{frame}#{RESET} #{message}"
|
|
134
138
|
old_stdout.flush
|
|
@@ -190,7 +194,7 @@ module Odysseus
|
|
|
190
194
|
$stdout = wr
|
|
191
195
|
begin
|
|
192
196
|
result = yield
|
|
193
|
-
rescue => e
|
|
197
|
+
rescue StandardError => e
|
|
194
198
|
err = e
|
|
195
199
|
ensure
|
|
196
200
|
done = true
|
|
@@ -199,7 +203,7 @@ module Odysseus
|
|
|
199
203
|
end
|
|
200
204
|
|
|
201
205
|
frame_idx = 0
|
|
202
|
-
buf =
|
|
206
|
+
buf = ''
|
|
203
207
|
|
|
204
208
|
loop do
|
|
205
209
|
# Non-blocking read from pipe
|
|
@@ -216,6 +220,7 @@ module Odysseus
|
|
|
216
220
|
while (nl = buf.index("\n"))
|
|
217
221
|
line = buf.slice!(0..nl).strip
|
|
218
222
|
next if line.empty?
|
|
223
|
+
|
|
219
224
|
line = clean_line(line)
|
|
220
225
|
next unless line
|
|
221
226
|
|
|
@@ -263,6 +268,7 @@ module Odysseus
|
|
|
263
268
|
end
|
|
264
269
|
|
|
265
270
|
raise err if err
|
|
271
|
+
|
|
266
272
|
result
|
|
267
273
|
end
|
|
268
274
|
|
|
@@ -289,19 +295,24 @@ module Odysseus
|
|
|
289
295
|
puts " #{MINT}✓#{RESET} #{message}"
|
|
290
296
|
end
|
|
291
297
|
|
|
292
|
-
|
|
293
|
-
|
|
298
|
+
# `io` is for the commands whose stdout is data rather than chatter:
|
|
299
|
+
# `odysseus logs web1 > app.log` captures a log stream, and a notice about
|
|
300
|
+
# which container the logs came from does not belong in it. A default
|
|
301
|
+
# rather than a second set of methods, so every other caller keeps writing
|
|
302
|
+
# to stdout exactly as before.
|
|
303
|
+
def error(message, io: $stdout)
|
|
304
|
+
io.puts " #{RED}✗#{RESET} #{message}"
|
|
294
305
|
end
|
|
295
306
|
|
|
296
|
-
def warn(message)
|
|
297
|
-
puts " \e[33m!#{RESET} #{message}"
|
|
307
|
+
def warn(message, io: $stdout)
|
|
308
|
+
io.puts " \e[33m!#{RESET} #{message}"
|
|
298
309
|
end
|
|
299
310
|
|
|
300
|
-
def step(message)
|
|
311
|
+
def step(message, io: $stdout)
|
|
301
312
|
if debug?
|
|
302
|
-
puts " #{redact(message)}"
|
|
313
|
+
io.puts " #{redact(message)}"
|
|
303
314
|
else
|
|
304
|
-
puts " #{DIM}›#{RESET} #{message}"
|
|
315
|
+
io.puts " #{DIM}›#{RESET} #{message}"
|
|
305
316
|
end
|
|
306
317
|
end
|
|
307
318
|
|
|
@@ -318,12 +329,12 @@ module Odysseus
|
|
|
318
329
|
[h.to_s.length, rows.map { |r| r[i].to_s.length }.max || 0].max
|
|
319
330
|
end
|
|
320
331
|
|
|
321
|
-
header_line = headers.map.with_index { |h, i| h.to_s.ljust(widths[i]) }.join(
|
|
332
|
+
header_line = headers.map.with_index { |h, i| h.to_s.ljust(widths[i]) }.join(' ')
|
|
322
333
|
puts " #{COPPER}#{header_line}#{RESET}"
|
|
323
334
|
puts " #{widths.map { |w| '─' * w }.join(' ')}"
|
|
324
335
|
|
|
325
336
|
rows.each do |row|
|
|
326
|
-
line = row.map.with_index { |c, i| c.to_s.ljust(widths[i]) }.join(
|
|
337
|
+
line = row.map.with_index { |c, i| c.to_s.ljust(widths[i]) }.join(' ')
|
|
327
338
|
puts " #{line}"
|
|
328
339
|
end
|
|
329
340
|
end
|
|
@@ -341,15 +352,15 @@ module Odysseus
|
|
|
341
352
|
# --- Deploy-specific helpers ---
|
|
342
353
|
|
|
343
354
|
def deploy_header(service:, image:, image_tag:, build: false, distribution: nil)
|
|
344
|
-
header
|
|
345
|
-
info
|
|
346
|
-
info
|
|
347
|
-
info
|
|
355
|
+
header 'Odysseus Deploy'
|
|
356
|
+
info 'Service', service
|
|
357
|
+
info 'Image', "#{image}:#{image_tag}"
|
|
358
|
+
info 'Distribute', distribution if build && distribution
|
|
348
359
|
blank
|
|
349
360
|
end
|
|
350
361
|
|
|
351
362
|
def deploy_complete(duration: nil)
|
|
352
|
-
msg =
|
|
363
|
+
msg = 'Deployment successful'
|
|
353
364
|
msg += " in #{duration}s" if duration
|
|
354
365
|
step_ok msg
|
|
355
366
|
end
|
|
@@ -421,9 +432,7 @@ module Odysseus
|
|
|
421
432
|
|
|
422
433
|
# Map known messages to clean versions
|
|
423
434
|
CLEAN_MESSAGES.each do |pattern, replacement|
|
|
424
|
-
if line.match?(pattern)
|
|
425
|
-
return line.sub(pattern, replacement)
|
|
426
|
-
end
|
|
435
|
+
return line.sub(pattern, replacement) if line.match?(pattern)
|
|
427
436
|
end
|
|
428
437
|
|
|
429
438
|
line
|
|
@@ -440,8 +449,9 @@ module Odysseus
|
|
|
440
449
|
/^Pushing to (.+)\.\.\./ => 'Pushing image to \1',
|
|
441
450
|
/^Starting (.+)\.\.\.$/ => 'Starting \1',
|
|
442
451
|
/^Stopping (.+) .*/ => 'Stopping \1',
|
|
443
|
-
/^Attaching (.+) to proxy.*/ => 'Attaching \1 to proxy'
|
|
452
|
+
/^Attaching (.+) to proxy.*/ => 'Attaching \1 to proxy'
|
|
444
453
|
}.freeze
|
|
454
|
+
private_constant :CLEAN_MESSAGES
|
|
445
455
|
end
|
|
446
456
|
end
|
|
447
457
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: odysseus-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas
|
|
@@ -15,56 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 0.10.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: ratatui_ruby
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '1.4'
|
|
33
|
-
type: :runtime
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '1.4'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: rspec
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '3.12'
|
|
47
|
-
type: :development
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '3.12'
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: pry-byebug
|
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '3.10'
|
|
61
|
-
type: :development
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '3.10'
|
|
25
|
+
version: 0.10.0
|
|
68
26
|
description: Command-line interface for deploying with Odysseus
|
|
69
27
|
email:
|
|
70
28
|
- thomas@imfiny.com
|
|
@@ -73,14 +31,25 @@ executables:
|
|
|
73
31
|
extensions: []
|
|
74
32
|
extra_rdoc_files: []
|
|
75
33
|
files:
|
|
34
|
+
- CHANGELOG.md
|
|
35
|
+
- LICENSE.txt
|
|
76
36
|
- README.md
|
|
77
37
|
- bin/odysseus
|
|
78
38
|
- lib/odysseus/cli/cli.rb
|
|
39
|
+
- lib/odysseus/cli/doctor_commands.rb
|
|
40
|
+
- lib/odysseus/cli/interactive_commands.rb
|
|
41
|
+
- lib/odysseus/cli/rollback_commands.rb
|
|
42
|
+
- lib/odysseus/cli/setup_commands.rb
|
|
79
43
|
- lib/odysseus/cli/ui.rb
|
|
44
|
+
- lib/odysseus/cli/version.rb
|
|
80
45
|
homepage: https://github.com/WA-Systems-EU/odysseus
|
|
81
46
|
licenses:
|
|
82
|
-
-
|
|
83
|
-
metadata:
|
|
47
|
+
- MIT
|
|
48
|
+
metadata:
|
|
49
|
+
homepage_uri: https://github.com/WA-Systems-EU/odysseus
|
|
50
|
+
source_code_uri: https://github.com/WA-Systems-EU/odysseus
|
|
51
|
+
changelog_uri: https://github.com/WA-Systems-EU/odysseus/blob/trunk/odysseus-cli/CHANGELOG.md
|
|
52
|
+
rubygems_mfa_required: 'true'
|
|
84
53
|
rdoc_options: []
|
|
85
54
|
require_paths:
|
|
86
55
|
- lib
|
|
@@ -88,14 +57,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
88
57
|
requirements:
|
|
89
58
|
- - ">="
|
|
90
59
|
- !ruby/object:Gem::Version
|
|
91
|
-
version:
|
|
60
|
+
version: 3.2.0
|
|
92
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
62
|
requirements:
|
|
94
63
|
- - ">="
|
|
95
64
|
- !ruby/object:Gem::Version
|
|
96
65
|
version: '0'
|
|
97
66
|
requirements: []
|
|
98
|
-
rubygems_version:
|
|
67
|
+
rubygems_version: 4.0.19
|
|
99
68
|
specification_version: 4
|
|
100
69
|
summary: CLI for Odysseus deployment tool
|
|
101
70
|
test_files: []
|