kuby-core 0.11.2 → 0.11.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3a59a9d3e923807647da18d834d994cc7b2d149f4c82d6d9966d72748d7bcd5
4
- data.tar.gz: 2bbd8e7d1c92ed3d0eb7d6d05420d7119d6f20a249f4401e52191868baeb0996
3
+ metadata.gz: 3e4b89049516b86853e5b3b4d41b4484cafae1244468d6721d5410af0ca071d1
4
+ data.tar.gz: 2b1d09c7e479cefd8b085dd4313d4f1ae4294b1b9fc4c6c22d713036b07178bf
5
5
  SHA512:
6
- metadata.gz: d8bf5fce8051029c8231e915035ec6c704ab361a6008b5335bf8a6747fb106ed55869164bb15eb704ecd72e6366ee320664d23d128a74726b6ca320edcb5c442
7
- data.tar.gz: 679ad59207c201fb710e47e69c4682676a6fb12c826b59350a74d98c48f212d358c50fde0f8da0a5804391738d442a839cb4560d2cebd61ec7e7955677bd8e53
6
+ metadata.gz: 3ae4889774de571b2198fde29edf5b9f58386c3f97f75d44d9e17a31c88b954f83dca6046ac41b2d5b18615d99b6a00b87e0d33136bc3515c46be6e46316eeb5
7
+ data.tar.gz: c43d154adad210913a7c181c41ff8cdabde9f60e6dff6719666c7b1ca6c4077686e8cadf8ac6cbf534c74e3de9f627f8ef6079d92958969b07d48b58acd585d9
@@ -1,3 +1,25 @@
1
+ ## 0.11.8
2
+ * Alias Rails `config_map` to `env`.
3
+
4
+ ## 0.11.7
5
+ * Properly namespace constant lookup for `Kubernetes::MissingPluginError`.
6
+ * Add missing `#storage` method for Postgres plugin.
7
+
8
+ ## 0.11.6
9
+ * Fix Rails generator.
10
+ - Causing `undefined method 'module_parent_name'`. Apparently `module_parent_name` wasn't introduced until Rails 6.
11
+
12
+ ## 0.11.5
13
+ * Raise friendlier error when attempting to add Docker credentials in the development environment.
14
+ * Raise friendlier error when attempting to set a username and password for SQLite databases.
15
+
16
+ ## 0.11.4
17
+ * Fix bug causing crash when running CLI commands.
18
+ - Turns out was caused by adding a Sorbet type annotation inside an anonymous singleton class and forgetting to extend `T::Sig`. Thanks @lazyatom!
19
+
20
+ ## 0.11.3
21
+ * I've gone back and forth a few times on this, but I decided to put the initializer code back into the Rails generator.
22
+
1
23
  ## 0.11.2
2
24
  * Attempt to auto-require the requested provider if it isn't registered.
3
25
  * Adjust error message when provider can't be found to include reminder to add a require statement.
@@ -59,8 +59,10 @@ module Kuby
59
59
  tls_enabled false
60
60
 
61
61
  database do
62
- user(DEFAULT_DB_USER) if respond_to?(:user)
63
- password(DEFAULT_DB_PASSWORD) if respond_to?(:password)
62
+ if requires_credentials?
63
+ user(DEFAULT_DB_USER)
64
+ password(DEFAULT_DB_PASSWORD)
65
+ end
64
66
  end
65
67
  end
66
68
 
@@ -1,9 +1,11 @@
1
- # typed: true
1
+ # typed: strict
2
+
2
3
  require 'kuby/version'
3
4
  require 'gli'
4
5
 
5
6
  module Kuby
6
7
  class Commands
8
+ extend T::Sig
7
9
  extend GLI::App
8
10
 
9
11
  # GLI doesn't have a wildcard option, so it's impossible to tell it to
@@ -17,8 +19,12 @@ module Kuby
17
19
  # avoid the usual series of cryptic alias_method calls (note that there
18
20
  # is no singleton class version of #prepend in the Ruby language).
19
21
  singleton_class.send(:prepend, Module.new do
22
+ extend T::Sig
23
+
24
+ sig { params(args: T::Array[String]).void }
20
25
  def run(args)
21
26
  if idx = args.index('rails') || idx = args.index('rake')
27
+ @rails_options = T.let(@rails_options, T.nilable(T::Array[String]))
22
28
  @rails_options = args[idx..-1]
23
29
  super(args[0..idx])
24
30
  else
@@ -27,10 +33,12 @@ module Kuby
27
33
  end
28
34
  end)
29
35
 
36
+ sig { returns(Kuby::Tasks) }
30
37
  def self.tasks
31
38
  Kuby::Tasks.new(Kuby.environment)
32
39
  end
33
40
 
41
+ sig { void }
34
42
  def self.must_be_dev_env!
35
43
  unless Kuby.environment.development?
36
44
  fail "Command not supported in the '#{Kuby.environment.name}' environment"
@@ -67,6 +75,7 @@ module Kuby
67
75
  rc.action do |global_options, options, args|
68
76
  must_be_dev_env!
69
77
  exit 1 unless tasks.dev_deployment_ok
78
+ @rails_options = T.let(@rails_options, T.nilable(T::Array[String]))
70
79
  Kuby::RailsCommands.run(@rails_options)
71
80
  end
72
81
 
@@ -1,12 +1,24 @@
1
- # typed: true
1
+ # typed: strict
2
+
2
3
  module Kuby
3
4
  class Definition
5
+ extend T::Sig
6
+
7
+ sig { returns(String) }
4
8
  attr_reader :app_name
5
9
 
10
+ sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
6
11
  def initialize(app_name, &block)
7
12
  @app_name = app_name
13
+ @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
8
14
  end
9
15
 
16
+ sig {
17
+ params(
18
+ name: Symbol,
19
+ block: T.nilable(T.proc.void)
20
+ ).returns(Environment)
21
+ }
10
22
  def environment(name = Kuby.env, &block)
11
23
  name = name.to_s
12
24
 
@@ -16,9 +28,10 @@ module Kuby
16
28
  environments[name].instance_eval(&block)
17
29
  end
18
30
 
19
- environments[name]
31
+ T.must(environments[name])
20
32
  end
21
33
 
34
+ sig { returns(T::Hash[Symbol, Environment]) }
22
35
  def environments
23
36
  @environments ||= {}
24
37
  end
@@ -1,19 +1,34 @@
1
- # typed: true
1
+ # typed: strict
2
+
2
3
  module Kuby
3
4
  class Spinner
4
- PIECES = %w(- \\ | /).freeze
5
- INTERVAL = 0.2 # seconds
6
-
7
- def self.spin(message)
5
+ extend T::Sig
6
+
7
+ PIECES = T.let(%w(- \\ | /).freeze, T::Array[String])
8
+ INTERVAL = T.let(0.2, Float) # seconds
9
+
10
+ sig {
11
+ params(
12
+ message: String,
13
+ block: T.proc.params(spinner: Spinner).void
14
+ )
15
+ .void
16
+ }
17
+ def self.spin(message, &block)
8
18
  yield new(message)
9
19
  end
10
20
 
11
- attr_reader :message, :status
21
+ sig { returns(String) }
22
+ attr_reader :message
23
+
24
+ sig { returns(Symbol) }
25
+ attr_reader :status
12
26
 
27
+ sig { params(message: String).void }
13
28
  def initialize(message)
14
- @message = message
15
- @status = :running
16
- @thread = Thread.new do
29
+ @message = T.let(message, String)
30
+ @status = T.let(:running, Symbol)
31
+ @thread = T.let(Thread.new do
17
32
  counter = 0
18
33
 
19
34
  while true
@@ -33,14 +48,16 @@ module Kuby
33
48
  end
34
49
 
35
50
  puts
36
- end
51
+ end, Thread)
37
52
  end
38
53
 
54
+ sig { void }
39
55
  def success
40
56
  @status = :success
41
57
  @thread.join
42
58
  end
43
59
 
60
+ sig { void }
44
61
  def failure
45
62
  @status = :failure
46
63
  @thread.join
@@ -48,66 +65,116 @@ module Kuby
48
65
  end
49
66
 
50
67
  class SetupTask
51
- attr_reader :message, :callable
68
+ extend T::Sig
52
69
 
70
+ sig { returns(String) }
71
+ attr_reader :message
72
+
73
+ sig { returns(T.proc.void) }
74
+ attr_reader :callable
75
+
76
+ sig { params(message: String, callable: T.proc.void).void }
53
77
  def initialize(message, callable)
54
78
  @message = message
55
79
  @callable = callable
56
80
  end
57
81
 
82
+ sig { void }
58
83
  def run
59
84
  callable.call
60
85
  end
61
86
  end
62
87
 
63
88
  class Pipe
64
- attr_reader :name, :cli, :out, :err
89
+ extend T::Sig
90
+
91
+ sig { returns(Symbol) }
92
+ attr_reader :name
93
+
94
+ sig { returns(T.untyped) }
95
+ attr_reader :cli
65
96
 
97
+ sig { returns(StringIO) }
98
+ attr_reader :out
99
+
100
+ sig { returns(StringIO) }
101
+ attr_reader :err
102
+
103
+ sig { params(name: Symbol, cli: T.untyped).void }
66
104
  def initialize(name, cli)
67
- @name = name
68
- @cli = cli
69
- @out = StringIO.new
70
- @err = StringIO.new
105
+ @name = T.let(name, Symbol)
106
+ @cli = T.let(cli, T.untyped)
107
+ @out = T.let(StringIO.new, StringIO)
108
+ @err = T.let(StringIO.new, StringIO)
71
109
  end
72
110
 
111
+ sig { params(block: T.proc.void).void }
73
112
  def wrap(&block)
74
113
  cli.with_pipes(out, err) do
75
114
  block.call
76
115
  end
77
116
  end
78
117
 
118
+ sig { returns(T::Boolean) }
79
119
  def success?
80
120
  cli.last_status.nil? || cli.last_status.success?
81
121
  end
82
122
  end
83
123
 
84
124
  class Pipes
125
+ extend T::Sig
126
+ extend T::Generic
127
+
85
128
  include Enumerable
86
129
 
87
- attr_reader :pipes, :ex
130
+ Elem = type_member(fixed: Pipe)
131
+
132
+ sig { returns(T::Array[Pipe]) }
133
+ attr_reader :pipes
88
134
 
135
+ sig { returns(T.nilable(StandardError)) }
136
+ attr_reader :ex
137
+
138
+ sig { params(clis: T::Hash[Symbol, T.untyped]).returns(Pipes) }
89
139
  def self.build(clis)
90
140
  new(clis.map { |name, cli| Pipe.new(name, cli) })
91
141
  end
92
142
 
143
+ sig { params(pipes: T::Array[Pipe]).void }
93
144
  def initialize(pipes)
94
- @pipes = pipes
145
+ @ex = T.let(@ex, T.nilable(StandardError))
146
+ @pipes = T.let(pipes, T::Array[Pipe])
95
147
  end
96
148
 
149
+ sig {
150
+ override.params(
151
+ block: T.proc.params(package: Pipe).void
152
+ )
153
+ .void
154
+ }
97
155
  def each(&block)
98
156
  pipes.each(&block)
99
157
  end
100
158
 
159
+ sig { params(block: T.proc.void).void }
101
160
  def wrap(&block)
102
161
  do_wrap(pipes, &block)
103
162
  end
104
163
 
164
+ sig { returns(T::Boolean) }
105
165
  def success?
106
166
  pipes.all?(&:success?) && !ex
107
167
  end
108
168
 
109
169
  private
110
170
 
171
+ sig {
172
+ params(
173
+ remaining_pipes: T::Array[Pipe],
174
+ block: T.proc.void
175
+ )
176
+ .void
177
+ }
111
178
  def do_wrap(remaining_pipes, &block)
112
179
  if remaining_pipes.empty?
113
180
  begin
@@ -119,20 +186,28 @@ module Kuby
119
186
  return
120
187
  end
121
188
 
122
- remaining_pipes[0].wrap do
123
- do_wrap(remaining_pipes[1..-1], &block)
189
+ T.must(remaining_pipes[0]).wrap do
190
+ do_wrap(T.must(remaining_pipes[1..-1]), &block)
124
191
  end
125
192
  end
126
193
  end
127
194
 
128
195
  class SetupTaskList
129
- attr_reader :tasks, :clis
196
+ extend T::Sig
197
+
198
+ sig { returns(T::Array[SetupTask]) }
199
+ attr_reader :tasks
130
200
 
201
+ sig { returns T::Hash[Symbol, T.untyped] }
202
+ attr_reader :clis
203
+
204
+ sig { params(tasks: T::Array[SetupTask], clis: T::Hash[Symbol, T.untyped]).void }
131
205
  def initialize(tasks, clis)
132
206
  @tasks = tasks
133
207
  @clis = clis
134
208
  end
135
209
 
210
+ sig { void }
136
211
  def run
137
212
  tasks.each do |task|
138
213
  pipes = Pipes.build(clis)
@@ -160,6 +235,7 @@ module Kuby
160
235
 
161
236
  private
162
237
 
238
+ sig { params(pipe: Pipe).void }
163
239
  def print_streams(pipe)
164
240
  unless pipe.out.string.strip.empty?
165
241
  puts("========= #{pipe.name.upcase} STDOUT ========")
@@ -172,27 +248,37 @@ module Kuby
172
248
  end
173
249
  end
174
250
 
251
+ sig { params(ex: T.nilable(StandardError)).void }
175
252
  def print_error(ex)
176
253
  return unless ex
177
254
  puts("========= RUBY ERROR ========")
178
255
  puts(ex.message)
179
- puts(ex.backtrace.join("\n"))
256
+ puts(T.must(ex.backtrace).join("\n"))
180
257
  end
181
258
  end
182
259
 
183
260
  class DevSetup
261
+ extend T::Sig
262
+
263
+ sig { returns(Environment) }
184
264
  attr_reader :environment
185
265
 
266
+ sig { params(environment: Environment).void }
186
267
  def initialize(environment)
187
- @environment = environment
268
+ @environment = T.let(environment, Environment)
269
+ @setup_tasks = T.let(@setup_tasks, T.nilable(T::Array[SetupTask]))
270
+ @clis = T.let(@clis, T.nilable(T::Hash[Symbol, T.untyped]))
271
+ @tasks = T.let(@tasks, T.nilable(Tasks))
188
272
  end
189
273
 
274
+ sig { void }
190
275
  def run
191
276
  SetupTaskList.new(setup_tasks, clis).run
192
277
  end
193
278
 
194
279
  private
195
280
 
281
+ sig { returns(T::Array[SetupTask]) }
196
282
  def setup_tasks
197
283
  @setup_tasks ||= [
198
284
  SetupTask.new(
@@ -231,14 +317,17 @@ module Kuby
231
317
  ]
232
318
  end
233
319
 
320
+ sig { returns(Kubernetes::Spec) }
234
321
  def kubernetes
235
322
  environment.kubernetes
236
323
  end
237
324
 
325
+ sig { returns(Docker::Spec) }
238
326
  def docker
239
327
  environment.docker
240
328
  end
241
329
 
330
+ sig { returns T::Hash[Symbol, T.untyped] }
242
331
  def clis
243
332
  @clis ||= {
244
333
  kubectl: kubernetes.provider.kubernetes_cli,
@@ -249,6 +338,7 @@ module Kuby
249
338
  }
250
339
  end
251
340
 
341
+ sig { returns(Tasks) }
252
342
  def tasks
253
343
  @tasks ||= Kuby::Tasks.new(environment)
254
344
  end
@@ -115,6 +115,13 @@ module Kuby
115
115
  layer_stack.includes?(name)
116
116
  end
117
117
 
118
+ sig {
119
+ params(block: T.nilable(T.proc.void)).returns(Credentials)
120
+ }
121
+ def credentials(&block)
122
+ raise 'Docker credentials are not supported in the development environment'
123
+ end
124
+
118
125
  sig { returns(Dockerfile) }
119
126
  def to_dockerfile
120
127
  Dockerfile.new.tap do |df|
@@ -12,7 +12,7 @@ module Kuby
12
12
  plugins_by_env = plugins[plugin_name]
13
13
 
14
14
  unless plugins_by_env
15
- raise MissingPluginError, "no plugin registered with name #{plugin_name}, "\
15
+ raise Kubernetes::MissingPluginError, "no plugin registered with name #{plugin_name}, "\
16
16
  'do you need to add a gem to your Gemfile?'
17
17
  end
18
18
 
@@ -3,7 +3,25 @@ require 'rails/generators'
3
3
  require 'rails/generators/base'
4
4
 
5
5
  class KubyGenerator < Rails::Generators::Base
6
+ def create_initializer_file
7
+ create_file(
8
+ File.join(*%w(config initializers kuby.rb)),
9
+ <<~END
10
+ require 'kuby'
11
+ Kuby.load!
12
+ END
13
+ )
14
+ end
15
+
6
16
  def create_config_file
17
+ app_class = Rails.application.class
18
+
19
+ app_name = if app_class.respond_to?(:module_parent_name)
20
+ app_class.module_parent_name
21
+ else
22
+ app_class.parent_name
23
+ end
24
+
7
25
  create_file(
8
26
  'kuby.rb',
9
27
  <<~END
@@ -11,7 +29,7 @@ class KubyGenerator < Rails::Generators::Base
11
29
  require 'active_support/encrypted_configuration'
12
30
 
13
31
  # Define a production Kuby deploy environment
14
- Kuby.define('#{Rails.application.class.module_parent_name}') do
32
+ Kuby.define('#{app_name}') do
15
33
  environment(:production) do
16
34
  # Because the Rails environment isn't always loaded when
17
35
  # your Kuby config is loaded, provide access to Rails
@@ -1,4 +1,5 @@
1
1
  # typed: false
2
+
2
3
  require 'kube-dsl'
3
4
  require 'kuby/kube-db'
4
5
 
@@ -15,6 +16,10 @@ module Kuby
15
16
  @configs = configs
16
17
  end
17
18
 
19
+ def requires_credentials?
20
+ true
21
+ end
22
+
18
23
  def name
19
24
  :mysql
20
25
  end
@@ -202,6 +202,8 @@ module Kuby
202
202
  @config_map
203
203
  end
204
204
 
205
+ alias_method :env, :config_map
206
+
205
207
  def app_secrets(&block)
206
208
  spec = self
207
209
 
@@ -1,4 +1,5 @@
1
1
  # typed: false
2
+
2
3
  require 'kube-dsl'
3
4
  require 'kuby/kube-db'
4
5
 
@@ -18,6 +19,10 @@ module Kuby
18
19
  password(config['password'])
19
20
  end
20
21
 
22
+ def requires_credentials?
23
+ true
24
+ end
25
+
21
26
  def name
22
27
  :postgres
23
28
  end
@@ -58,6 +63,20 @@ module Kuby
58
63
  end
59
64
  end
60
65
  end
66
+
67
+ def storage(amount)
68
+ database do
69
+ spec do
70
+ storage do
71
+ resources do
72
+ requests do
73
+ set :storage, amount
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
61
80
 
62
81
  def secret(&block)
63
82
  context = self
@@ -1,4 +1,5 @@
1
1
  # typed: true
2
+
2
3
  module Kuby
3
4
  module Plugins
4
5
  module RailsApp
@@ -14,6 +15,18 @@ module Kuby
14
15
  environment.docker.package_phase.add(:sqlite_client)
15
16
  end
16
17
 
18
+ def requires_credentials?
19
+ false
20
+ end
21
+
22
+ def user(_user)
23
+ raise 'SQLite databases do not require a username or password'
24
+ end
25
+
26
+ def password(_password)
27
+ raise 'SQLite databases do not require a username or password'
28
+ end
29
+
17
30
  def name
18
31
  :sqlite
19
32
  end
@@ -1,5 +1,5 @@
1
- # typed: strict
1
+ # typed: true
2
2
 
3
3
  module Kuby
4
- VERSION = '0.11.2'
4
+ VERSION = '0.11.8'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kuby-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.11.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Dutro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-10 00:00:00.000000000 Z
11
+ date: 2020-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize