odysseus-cli 0.3.0 → 0.9.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.
@@ -35,8 +35,8 @@ module Odysseus
35
35
  @io.respond_to?(method, include_private)
36
36
  end
37
37
 
38
- def method_missing(method, *args, &block)
39
- @io.send(method, *args, &block)
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
- begin
120
- result = yield
121
- rescue => e
122
- err = e
123
- ensure
124
- done = true
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
- def error(message)
293
- puts " #{RED}✗#{RESET} #{message}"
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 "Odysseus Deploy"
345
- info "Service", service
346
- info "Image", "#{image}:#{image_tag}"
347
- info "Distribute", distribution if build && distribution
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 = "Deployment successful"
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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Odysseus
4
+ module CLI
5
+ VERSION = '0.9.0'
6
+ end
7
+ 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.3.0
4
+ version: 0.9.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: '0.2'
18
+ version: 0.9.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: '0.2'
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.9.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
- - LGPL-3.0-only
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: '3.0'
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: 3.6.9
67
+ rubygems_version: 4.0.16
99
68
  specification_version: 4
100
69
  summary: CLI for Odysseus deployment tool
101
70
  test_files: []