capistrano-data_plane_api 0.1.4 → 0.2.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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -2
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +7 -4
  6. data/Gemfile.lock +108 -69
  7. data/README.md +5 -0
  8. data/capistrano-data_plane_api.gemspec +5 -2
  9. data/exe/cap_data_plane_api +3 -2
  10. data/lib/capistrano/data_plane_api/configuration/backend.rb +2 -0
  11. data/lib/capistrano/data_plane_api/configuration/server.rb +4 -2
  12. data/lib/capistrano/data_plane_api/configuration/symbol.rb +2 -0
  13. data/lib/capistrano/data_plane_api/configuration.rb +3 -3
  14. data/lib/capistrano/data_plane_api/deploy/args.rb +71 -40
  15. data/lib/capistrano/data_plane_api/deploy/deployment_stats.rb +29 -25
  16. data/lib/capistrano/data_plane_api/deploy/group.rb +33 -24
  17. data/lib/capistrano/data_plane_api/deploy/helper.rb +3 -5
  18. data/lib/capistrano/data_plane_api/deploy/server_stats.rb +60 -43
  19. data/lib/capistrano/data_plane_api/deploy.rb +3 -2
  20. data/lib/capistrano/data_plane_api/diggable.rb +5 -2
  21. data/lib/capistrano/data_plane_api/equatable.rb +4 -2
  22. data/lib/capistrano/data_plane_api/helper.rb +31 -27
  23. data/lib/capistrano/data_plane_api/hooks.rb +1 -0
  24. data/lib/capistrano/data_plane_api/show_state.rb +15 -12
  25. data/lib/capistrano/data_plane_api/tasks.rb +26 -2
  26. data/lib/capistrano/data_plane_api/terminal_print_loop.rb +7 -4
  27. data/lib/capistrano/data_plane_api/type.rb +9 -5
  28. data/lib/capistrano/data_plane_api/version.rb +2 -2
  29. data/lib/capistrano/data_plane_api.rb +96 -74
  30. data/lib/capistrano-data_plane_api.rb +4 -0
  31. data/rbi/capistrano-data_plane_api.rbi +283 -0
  32. data/sorbet/config +6 -0
  33. data/sorbet/rbi/annotations/.gitattributes +1 -0
  34. data/sorbet/rbi/annotations/faraday.rbi +17 -0
  35. data/sorbet/rbi/annotations/minitest.rbi +119 -0
  36. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  37. data/sorbet/rbi/annotations/webmock.rbi +9 -0
  38. data/sorbet/rbi/dsl/.gitattributes +1 -0
  39. data/sorbet/rbi/dsl/capistrano/data_plane_api/configuration/backend.rbi +50 -0
  40. data/sorbet/rbi/dsl/capistrano/data_plane_api/configuration/server.rbi +24 -0
  41. data/sorbet/rbi/dsl/capistrano/data_plane_api/configuration.rbi +52 -0
  42. data/sorbet/rbi/dsl/capistrano/data_plane_api/type.rbi +12 -0
  43. data/sorbet/rbi/gems/.gitattributes +1 -0
  44. data/sorbet/rbi/gems/addressable@2.8.7.rbi +1994 -0
  45. data/sorbet/rbi/gems/ast@2.4.3.rbi +585 -0
  46. data/sorbet/rbi/gems/base64@0.2.0.rbi +509 -0
  47. data/sorbet/rbi/gems/bigdecimal@3.1.9.rbi +8 -0
  48. data/sorbet/rbi/gems/booleans@0.1.3.rbi +28 -0
  49. data/sorbet/rbi/gems/byebug@12.0.0.rbi +37 -0
  50. data/sorbet/rbi/gems/crack@1.0.0.rbi +145 -0
  51. data/sorbet/rbi/gems/data_plane_api@0.2.0.rbi +238 -0
  52. data/sorbet/rbi/gems/faraday-net_http@3.4.0.rbi +147 -0
  53. data/sorbet/rbi/gems/faraday@2.13.0.rbi +2974 -0
  54. data/sorbet/rbi/gems/hashdiff@1.1.2.rbi +353 -0
  55. data/sorbet/rbi/gems/json@2.10.2.rbi +2113 -0
  56. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  57. data/sorbet/rbi/gems/logger@1.7.0.rbi +963 -0
  58. data/sorbet/rbi/gems/minitest@5.25.5.rbi +1547 -0
  59. data/sorbet/rbi/gems/net-http@0.6.0.rbi +4247 -0
  60. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  61. data/sorbet/rbi/gems/pastel@0.8.0.rbi +733 -0
  62. data/sorbet/rbi/gems/public_suffix@6.0.1.rbi +936 -0
  63. data/sorbet/rbi/gems/racc@1.8.1.rbi +160 -0
  64. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +404 -0
  65. data/sorbet/rbi/gems/rake@13.0.6.rbi +3030 -0
  66. data/sorbet/rbi/gems/rexml@3.4.1.rbi +5346 -0
  67. data/sorbet/rbi/gems/rubocop-espago@1.1.8.rbi +9 -0
  68. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  69. data/sorbet/rbi/gems/shale-builder@0.2.4.rbi +9 -0
  70. data/sorbet/rbi/gems/shale@1.2.2.rbi +2323 -0
  71. data/sorbet/rbi/gems/shoulda-context@2.0.0.rbi +563 -0
  72. data/sorbet/rbi/gems/strings-ansi@0.2.0.rbi +178 -0
  73. data/sorbet/rbi/gems/strings@0.2.1.rbi +830 -0
  74. data/sorbet/rbi/gems/thor@1.2.1.rbi +3957 -0
  75. data/sorbet/rbi/gems/tty-box@0.7.0.rbi +593 -0
  76. data/sorbet/rbi/gems/tty-color@0.6.0.rbi +241 -0
  77. data/sorbet/rbi/gems/tty-cursor@0.7.1.rbi +443 -0
  78. data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
  79. data/sorbet/rbi/gems/unicode_utils@1.4.0.rbi +184 -0
  80. data/sorbet/rbi/gems/uri@1.0.3.rbi +2349 -0
  81. data/sorbet/rbi/gems/vcr@6.3.1.rbi +3040 -0
  82. data/sorbet/rbi/gems/webmock@3.25.1.rbi +1792 -0
  83. data/sorbet/rbi/shims/gems/faraday.rbi +21 -0
  84. data/sorbet/rbi/shims/gems/shoulda-context@2.0.0.rbi +15 -0
  85. data/sorbet/rbi/todo.rbi +7 -0
  86. data/sorbet/tapioca/config.yml +28 -0
  87. data/sorbet/tapioca/extensions/load_gem.rb +1 -0
  88. data/sorbet/tapioca/require.rb +4 -0
  89. data/templates/bin/deploy.rb +1 -0
  90. metadata +106 -8
@@ -1,3 +1,4 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Capistrano
@@ -5,69 +6,79 @@ module Capistrano
5
6
  module Deploy
6
7
  # Represents the stats of a deployment to a particular server
7
8
  class ServerStats
8
- # @return [Boolean, nil] `nil` when the deployment hasn't begun
9
- # `true` when it has finished successfully, `false` when it has failed
10
- attr_accessor :success
9
+ # `nil` when the deployment hasn't begun
10
+ # `true` when it has finished successfully, `false` when it has failed
11
+ #
12
+ #: Symbol
13
+ attr_accessor :state
11
14
 
12
- # @return [Time, nil]
15
+ #: Time?
13
16
  attr_accessor :start_time
14
17
 
15
- # @return [Time, nil]
18
+ #: Time?
16
19
  attr_accessor :end_time
17
20
 
18
- # @return [String]
21
+ #: String
19
22
  attr_accessor :server_name
20
23
 
21
- # @return [String]
24
+ #: String
22
25
  attr_accessor :backend_name
23
26
 
24
- # @return [String, nil]
27
+ #: String
25
28
  attr_accessor :admin_state
26
29
 
27
- # @return [String, nil]
30
+ #: String
28
31
  attr_accessor :operational_state
29
32
 
30
- # @param server_name [String]
31
- # @param backend_name [String]
32
- def initialize(server_name, backend_name)
33
+ #: (String, String, Symbol, String, String) -> void
34
+ def initialize(
35
+ server_name,
36
+ backend_name,
37
+ state: :pending,
38
+ admin_state: 'unknown',
39
+ operational_state: 'unknown'
40
+ )
33
41
  @server_name = server_name
34
42
  @backend_name = backend_name
35
- @success = nil
36
- @seconds = nil
37
- @admin_state = 'unknown'
38
- @operational_state = 'unknown'
43
+ @state = state
44
+ @admin_state = admin_state
45
+ @operational_state = operational_state
46
+ @seconds = T.let(nil, T.nilable(Integer))
39
47
  end
40
48
 
41
- # @return [String]
49
+ #: -> String
42
50
  def to_s
43
51
  time_string =
44
- case @success
45
- when nil then 'skipped'
46
- when false then "failed after #{Helper.humanize_time(seconds)}"
47
- when true then "took #{Helper.humanize_time(seconds)}"
52
+ case @state
53
+ when :pending then 'skipped'
54
+ when :failed then "failed after #{Helper.humanize_time(T.must(seconds))}"
55
+ when :success then "took #{Helper.humanize_time(T.must(seconds))}"
56
+ when :info then "at #{Time.now}"
48
57
  end
49
58
 
50
59
  " #{state_emoji} #{server_title} #{time_string}#{haproxy_states}"
51
60
  end
52
61
 
53
- # @return [Integer, nil] How much time has the deployment taken
62
+ # How much time has the deployment taken
63
+ #
64
+ #: -> Integer?
54
65
  def seconds
55
- @seconds ||= Helper.seconds_since(@start_time, to: @end_time)
66
+ @seconds ||= Helper.seconds_since(T.must(@start_time), to: T.must(@end_time))
56
67
  end
57
68
 
58
69
  private
59
70
 
60
- # @return [String, nil]
71
+ #: -> String?
61
72
  def humanize_admin_state
62
73
  ::Capistrano::DataPlaneApi.humanize_admin_state(@admin_state)
63
74
  end
64
75
 
65
- # @return [String, nil]
76
+ #: -> String?
66
77
  def humanize_operational_state
67
78
  ::Capistrano::DataPlaneApi.humanize_operational_state(@operational_state)
68
79
  end
69
80
 
70
- # @return [String, nil]
81
+ #: -> String?
71
82
  def haproxy_states
72
83
  <<-HAPROXY
73
84
 
@@ -76,35 +87,41 @@ module Capistrano
76
87
  HAPROXY
77
88
  end
78
89
 
79
- # @return [Hash{String => Symbol}]
80
- SERVER_TITLE_COLORS = {
81
- nil => :yellow,
82
- false => :red,
83
- true => :green
84
- }.freeze
90
+ SERVER_TITLE_COLORS = T.let(
91
+ {
92
+ pending: :yellow,
93
+ failed: :red,
94
+ success: :green,
95
+ info: :blue,
96
+ }.freeze,
97
+ T::Hash[Symbol, Symbol],
98
+ )
85
99
  private_constant :SERVER_TITLE_COLORS
86
100
 
87
- # @return [String]
101
+ #: -> String
88
102
  def server_title
89
- COLORS.decorate(server_id, :bold, SERVER_TITLE_COLORS[@success])
103
+ COLORS.decorate(server_id, :bold, SERVER_TITLE_COLORS.fetch(@state))
90
104
  end
91
105
 
92
- # @return [String]
106
+ #: -> String
93
107
  def server_id
94
108
  "#{@backend_name}:#{@server_name}"
95
109
  end
96
110
 
97
- # @return [Hash{Boolean, nil => Symbol}]
98
- STATE_EMOJIS = {
99
- nil => '🟡',
100
- false => '❌',
101
- true => '✅'
102
- }.freeze
111
+ STATE_EMOJIS = T.let(
112
+ {
113
+ pending: '🟡',
114
+ failed: '❌',
115
+ success: '✅',
116
+ info: 'ℹ️',
117
+ }.freeze,
118
+ T::Hash[Symbol, String],
119
+ )
103
120
  private_constant :STATE_EMOJIS
104
121
 
105
- # @return [String]
122
+ #: -> String
106
123
  def state_emoji
107
- STATE_EMOJIS[@success]
124
+ STATE_EMOJIS.fetch(@state)
108
125
  end
109
126
  end
110
127
  end
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative '../data_plane_api'
@@ -7,13 +8,13 @@ module Capistrano
7
8
  # Contains code used in the deployment script.
8
9
  module Deploy
9
10
  class << self
10
- # @return [void]
11
+ #: -> void
11
12
  def call
12
13
  args = Args.parse
13
14
  puts COLORS.bold.blue('Running the deployment script')
14
15
 
15
16
  result = Group.call(args)
16
- abort if result == false
17
+ abort if result == :failed
17
18
  end
18
19
  end
19
20
  end
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Capistrano
@@ -5,13 +6,15 @@ module Capistrano
5
6
  # Include in a class to grant it the `#dig` method.
6
7
  # It's implemented so that it calls public methods.
7
8
  module Diggable
9
+ include Kernel
10
+
8
11
  # Extracts the nested value specified by the sequence of key objects by calling `dig` at each step,
9
12
  # returning `nil` if any intermediate step is `nil`.
10
13
  #
11
14
  # This implementation of `dig` uses `public_send` under the hood.
12
15
  #
13
16
  # @raise [TypeError] value has no #dig method
14
- # @return [Object]
17
+ #: (untyped) -> untyped
15
18
  def dig(*args)
16
19
  return unless args.size.positive?
17
20
 
@@ -19,7 +22,7 @@ module Capistrano
19
22
 
20
23
  value = public_send(key)
21
24
  return if value.nil?
22
- return value if args.size.zero?
25
+ return value if args.empty?
23
26
  raise ::TypeError, "#{value.class} does not have #dig method" unless value.respond_to?(:dig)
24
27
 
25
28
  value.dig(*args)
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Capistrano
@@ -6,8 +7,9 @@ module Capistrano
6
7
  # of comparing themselves with other objects of the same class
7
8
  # by calling `==` on their instance variables.
8
9
  module Equatable
9
- # @param other [Object]
10
- # @return [Boolean]
10
+ include Kernel
11
+
12
+ #: (Object) -> bool
11
13
  def eql?(other)
12
14
  return true if equal?(other)
13
15
  return false unless other.is_a?(self.class) || is_a?(other.class)
@@ -1,37 +1,43 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Capistrano
4
5
  module DataPlaneApi
5
6
  # Provides helper methods
6
7
  module Helper
7
- # @return [Hash{String => Symbol}]
8
- ADMIN_STATE_COLORS = {
9
- 'unknown' => :on_red,
10
- 'drain' => :on_blue,
11
- 'ready' => :on_green,
12
- 'maint' => :on_yellow
13
- }.freeze
14
-
15
- # @return [Hash{String => Symbol}]
16
- OPERATIONAL_STATE_COLORS = {
17
- 'unknown' => :on_red,
18
- 'up' => :on_green,
19
- 'down' => :on_red,
20
- 'stopping' => :on_yellow
21
- }.freeze
22
-
23
- # @return [Boolean]
8
+ ADMIN_STATE_COLORS = T.let(
9
+ {
10
+ 'unknown' => :on_red,
11
+ 'drain' => :on_blue,
12
+ 'ready' => :on_green,
13
+ 'maint' => :on_yellow,
14
+ }.freeze,
15
+ T::Hash[String, Symbol],
16
+ )
17
+
18
+ OPERATIONAL_STATE_COLORS = T.let(
19
+ {
20
+ 'unknown' => :on_red,
21
+ 'up' => :on_green,
22
+ 'down' => :on_red,
23
+ 'stopping' => :on_yellow,
24
+ }.freeze,
25
+ T::Hash[String, Symbol],
26
+ )
27
+
28
+ #: -> bool
24
29
  def no_haproxy?
25
- !::ENV['NO_HAPROXY'].nil? && !::ENV['NO_HAPROXY'].empty?
30
+ no_haproxy = ::ENV['NO_HAPROXY']
31
+ !no_haproxy.nil? && !no_haproxy.empty?
26
32
  end
27
33
 
28
- # @return [Boolean]
34
+ #: -> bool
29
35
  def force_haproxy?
30
- !::ENV['FORCE_HAPROXY'].nil? && !::ENV['FORCE_HAPROXY'].empty?
36
+ force_haproxy = ::ENV['FORCE_HAPROXY']
37
+ !force_haproxy.nil? && !force_haproxy.empty?
31
38
  end
32
39
 
33
- # @param state [String, Symbol, nil]
34
- # @return [String, nil]
40
+ #: (String | Symbol | nil) -> String?
35
41
  def humanize_admin_state(state)
36
42
  return unless state
37
43
 
@@ -39,8 +45,7 @@ module Capistrano
39
45
  COLORS.decorate(" #{state.upcase} ", :bold, ADMIN_STATE_COLORS[state.downcase])
40
46
  end
41
47
 
42
- # @param state [String, Symbol, nil]
43
- # @return [String, nil]
48
+ #: (String | Symbol | nil) -> String?
44
49
  def humanize_operational_state(state)
45
50
  return unless state
46
51
 
@@ -48,10 +53,9 @@ module Capistrano
48
53
  COLORS.decorate(" #{state.upcase} ", :bold, OPERATIONAL_STATE_COLORS[state.downcase])
49
54
  end
50
55
 
51
- # @param backend [Capistrano::DataPlaneApi::Configuration::Backend]
52
- # @return [String]
56
+ #: (Configuration::Backend) -> String
53
57
  def humanize_backend_name(backend)
54
- COLORS.decorate(" #{backend.name} ", *backend.styles)
58
+ T.unsafe(COLORS).decorate(" #{backend.name} ", *backend.styles) # rubocop:disable Sorbet/ForbidTUnsafe
55
59
  end
56
60
  end
57
61
  end
@@ -5,3 +5,4 @@ require_relative '../data_plane_api'
5
5
  after 'deploy:started', 'data_plane_api:server:set_drain'
6
6
  before 'deploy:publishing', 'data_plane_api:server:set_maint'
7
7
  after 'deploy:finished', 'data_plane_api:server:set_ready'
8
+ before 'deploy:check', 'data_plane_api:server:check'
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'pastel'
@@ -10,8 +11,8 @@ module Capistrano
10
11
  # HAProxy backends and servers to stdout.
11
12
  module ShowState
12
13
  class << self
13
- # @return [String]
14
- def call # rubocop:disable Metrics/MethodLength
14
+ #: -> String
15
+ def call
15
16
  pastel = ::Pastel.new
16
17
  result = ::String.new
17
18
 
@@ -25,10 +26,15 @@ module Capistrano
25
26
  c.timeout = 2
26
27
  end
27
28
 
28
- ::Capistrano::DataPlaneApi.configuration.backends.each do |backend|
29
+ ::Capistrano::DataPlaneApi.configuration.backends&.each do |backend|
29
30
  result << ::TTY::Box.frame(title: { top_left: backend_name(backend) }) do
30
31
  b = ::String.new
31
- servers = ::Capistrano::DataPlaneApi.get_backend_servers_settings(backend.name, config: config).body
32
+ servers =
33
+ ::Capistrano::DataPlaneApi.get_backend_servers_settings(
34
+ T.must(backend.name),
35
+ config: config,
36
+ ).body
37
+
32
38
  servers.each do |server|
33
39
  operational_state = operational_state(server)
34
40
  admin_state = admin_state(server)
@@ -42,6 +48,7 @@ module Capistrano
42
48
  b
43
49
 
44
50
  rescue Error, ::Faraday::ConnectionFailed, ::Faraday::TimeoutError
51
+ b = T.must(b)
45
52
  b << pastel.bold.bright_red('Unavailable!')
46
53
  b << "\n"
47
54
  b
@@ -53,27 +60,23 @@ module Capistrano
53
60
 
54
61
  private
55
62
 
56
- # @param server [Hash{String => Object}]
57
- # @return [String]
63
+ #: (Hash[String, untyped]) -> String?
58
64
  def operational_state(server)
59
65
  ::Capistrano::DataPlaneApi.humanize_operational_state(server['operational_state'])
60
66
  end
61
67
 
62
- # @param server [Hash{String => Object}]
63
- # @return [String]
68
+ #: (Hash[String, untyped]) -> String?
64
69
  def admin_state(server)
65
70
  ::Capistrano::DataPlaneApi.humanize_admin_state(server['admin_state'])
66
71
  end
67
72
 
68
- # @param server [Hash{String => Object}]
69
- # @return [String]
73
+ #: (Hash[String, untyped]) -> String?
70
74
  def server_name(server)
71
75
  pastel = ::Pastel.new
72
76
  pastel.bold server['name']
73
77
  end
74
78
 
75
- # @param backend [Capistrano::DataPlaneApi::Configuration::Backend]
76
- # @return [String]
79
+ #: (Configuration::Backend) -> String
77
80
  def backend_name(backend)
78
81
  pastel = ::Pastel.new
79
82
  pastel.decorate(" #{backend.name} ", *backend.styles)
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rake'
4
+ require 'capistrano/data_plane_api/deploy'
4
5
 
5
- namespace :data_plane_api do
6
- namespace :server do
6
+ namespace :data_plane_api do # rubocop:disable Metrics/BlockLength
7
+ namespace :server do # rubocop:disable Metrics/BlockLength
7
8
  desc "Set the server's admin state to DRAIN through the HAProxy Data Plane API"
8
9
  task :set_drain do
9
10
  on roles :web do
@@ -32,5 +33,28 @@ namespace :data_plane_api do
32
33
  ::Capistrano::DataPlaneApi.server_set_maint fetch(:stage), force: true
33
34
  end
34
35
  end
36
+
37
+ desc 'Check the state of the HaProxy server'
38
+ task :check do
39
+ on roles :web do
40
+ next if ::Capistrano::DataPlaneApi.no_haproxy?
41
+
42
+ c = ::Capistrano::DataPlaneApi::COLORS
43
+ server, backend = ::Capistrano::DataPlaneApi.find_server_and_backend(fetch(:stage))
44
+
45
+ state = ::Capistrano::DataPlaneApi.server_get_state(fetch(:stage))
46
+
47
+ stats = ::Capistrano::DataPlaneApi::Deploy::ServerStats.new(
48
+ server.name,
49
+ backend.name,
50
+ state: :info,
51
+ admin_state: state['admin_state'],
52
+ operational_state: state['operational_state'],
53
+ )
54
+
55
+ human_name = c.decorate(" #{backend.name}:#{server.name} ", *backend.styles)
56
+ puts "\nUpdates HaProxy state for #{human_name}\n#{stats}\n\n"
57
+ end
58
+ end
35
59
  end
36
60
  end
@@ -1,9 +1,12 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'tty/cursor'
4
5
 
5
6
  module Capistrano
6
7
  module DataPlaneApi
8
+ # Provides a method that renders
9
+ # strings in a terminal with the given interval.
7
10
  module TerminalPrintLoop
8
11
  class << self
9
12
  # Calls the passed block in an endless loop with a given interval
@@ -11,9 +14,9 @@ module Capistrano
11
14
  # It prints the `String` returned from the block and clears it
12
15
  # before another frame is printed.
13
16
  #
14
- # @yieldparam content [String]
15
- # @param interval [Integer] Number of seconds between each screen refresh
16
- def call(interval: 2)
17
+ # @param interval: Number of seconds between each screen refresh
18
+ #: (Integer) { (String) -> Object } -> void
19
+ def call(interval: 2, &_block)
17
20
  previous_line_count = 0
18
21
  previous_max_line_length = 0
19
22
  loop do
@@ -22,7 +25,7 @@ module Capistrano
22
25
 
23
26
  print ::TTY::Cursor.clear_lines(previous_line_count + 1)
24
27
 
25
- content = yielded if yielded.is_a?(::String) && content.length.zero?
28
+ content = yielded if yielded.is_a?(::String) && content.empty?
26
29
  line_count = 0
27
30
  max_line_length = 0
28
31
  content.each_line do |line|
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'shale'
@@ -7,20 +8,23 @@ require_relative 'equatable'
7
8
 
8
9
  module Capistrano
9
10
  module DataPlaneApi
11
+ # A Base class for all types of the Data Plane API request and response bodies
10
12
  class Type < ::Shale::Mapper
13
+ extend T::Helpers
14
+
15
+ abstract!
16
+
11
17
  include Diggable
12
18
  include Equatable
13
19
 
14
- alias to_h to_hash
20
+ def to_h = to_hash
15
21
 
16
- # @param key [Symbol, String]
17
- # @return [Object, nil]
22
+ #: (Symbol | String) -> Object?
18
23
  def [](key)
19
24
  public_send(key) if respond_to?(key)
20
25
  end
21
26
 
22
- # @param key [Symbol, String]
23
- # @param val [Object]
27
+ #: (Symbol | String, Object) -> void
24
28
  def []=(key, val)
25
29
  public_send(:"#{key}=", val)
26
30
  end
@@ -1,8 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Capistrano
4
5
  module DataPlaneApi
5
- # @return [String]
6
- VERSION = '0.1.4'
6
+ VERSION = '0.2.0'
7
7
  end
8
8
  end