kuby-core 0.11.1 → 0.11.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/kuby.rb +4 -2
- data/lib/kuby/basic_logger.rb +56 -8
- data/lib/kuby/cli_base.rb +51 -12
- data/lib/kuby/commands.rb +10 -1
- data/lib/kuby/definition.rb +15 -2
- data/lib/kuby/dev_setup.rb +113 -23
- data/lib/kuby/docker/cli.rb +10 -10
- data/lib/kuby/docker/dev_spec.rb +7 -0
- data/lib/kuby/kubernetes/spec.rb +18 -3
- data/lib/kuby/plugin_registry.rb +1 -1
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +19 -1
- data/lib/kuby/plugins/rails_app/mysql.rb +5 -0
- data/lib/kuby/plugins/rails_app/postgres.rb +19 -0
- data/lib/kuby/plugins/rails_app/sqlite.rb +13 -0
- data/lib/kuby/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f148347cc0c776aabc5062f1e051c96d94277fe91831100befabc6976bbd6cd8
|
4
|
+
data.tar.gz: 2dba80a00dd2f460ad80fc97ecbb333fa5cc4f6bbbe21f1ddc798c3383da0015
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca4e9a7342bde7b8c12623374648c9c4ca61d0dd78f36eaf729dcad17f6a8f23bd1b6ccbd51190c8499f459cdfce98fa7774ada82b314cf516236958d7c93d4f
|
7
|
+
data.tar.gz: 4d9f1dc0e672431c2828e9e2c96fe6c56bb410794dd32089e9443a65f4a0e51259e0c3f089477ab18b6760149586edddc17e6187e3dd76aa61215ec4dd8b5eed
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## 0.11.7
|
2
|
+
* Properly namespace constant lookup for `Kubernetes::MissingPluginError`.
|
3
|
+
* Add missing `#storage` method for Postgres plugin.
|
4
|
+
|
5
|
+
## 0.11.6
|
6
|
+
* Fix Rails generator.
|
7
|
+
- Causing `undefined method 'module_parent_name'`. Apparently `module_parent_name` wasn't introduced until Rails 6.
|
8
|
+
|
9
|
+
## 0.11.5
|
10
|
+
* Raise friendlier error when attempting to add Docker credentials in the development environment.
|
11
|
+
* Raise friendlier error when attempting to set a username and password for SQLite databases.
|
12
|
+
|
13
|
+
## 0.11.4
|
14
|
+
* Fix bug causing crash when running CLI commands.
|
15
|
+
- Turns out was caused by adding a Sorbet type annotation inside an anonymous singleton class and forgetting to extend `T::Sig`. Thanks @lazyatom!
|
16
|
+
|
17
|
+
## 0.11.3
|
18
|
+
* I've gone back and forth a few times on this, but I decided to put the initializer code back into the Rails generator.
|
19
|
+
|
20
|
+
## 0.11.2
|
21
|
+
* Attempt to auto-require the requested provider if it isn't registered.
|
22
|
+
* Adjust error message when provider can't be found to include reminder to add a require statement.
|
23
|
+
|
1
24
|
## 0.11.1
|
2
25
|
* Use integers for ports instead of strings to appease Kubernetes.
|
3
26
|
|
data/lib/kuby.rb
CHANGED
@@ -59,8 +59,10 @@ module Kuby
|
|
59
59
|
tls_enabled false
|
60
60
|
|
61
61
|
database do
|
62
|
-
|
63
|
-
|
62
|
+
if requires_credentials?
|
63
|
+
user(DEFAULT_DB_USER)
|
64
|
+
password(DEFAULT_DB_PASSWORD)
|
65
|
+
end
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
data/lib/kuby/basic_logger.rb
CHANGED
@@ -1,10 +1,30 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
|
+
|
2
3
|
require 'logger'
|
3
4
|
require 'colorized_string'
|
4
5
|
|
5
6
|
module Kuby
|
6
7
|
class BasicLogger < Logger
|
7
|
-
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig {
|
11
|
+
override.params(
|
12
|
+
logdev: T.any(String, IO, StringIO, NilClass),
|
13
|
+
shift_age: Integer,
|
14
|
+
shift_size: Integer,
|
15
|
+
level: Integer,
|
16
|
+
progname: T.nilable(String),
|
17
|
+
formatter: T.nilable(FormatterProcType),
|
18
|
+
datetime_format: T.nilable(String),
|
19
|
+
shift_period_suffix: T.nilable(String)
|
20
|
+
).void
|
21
|
+
}
|
22
|
+
def initialize(
|
23
|
+
logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
|
24
|
+
progname: nil, formatter: nil, datetime_format: nil,
|
25
|
+
shift_period_suffix: '%Y%m%d')
|
26
|
+
@logdev = T.let(@logdev, T.nilable(Logger::LogDevice))
|
27
|
+
|
8
28
|
super
|
9
29
|
|
10
30
|
self.formatter = proc do |_severity, _datetime, _progname, msg|
|
@@ -12,23 +32,51 @@ module Kuby
|
|
12
32
|
end
|
13
33
|
end
|
14
34
|
|
15
|
-
|
16
|
-
|
35
|
+
sig {
|
36
|
+
override.params(
|
37
|
+
progname_or_msg: T.untyped,
|
38
|
+
block: T.nilable(T.proc.returns(T.untyped))
|
39
|
+
).void
|
40
|
+
}
|
41
|
+
def info(progname_or_msg = nil, &block)
|
42
|
+
if block
|
43
|
+
super(progname_or_msg) { ColorizedString[block.call].yellow }
|
44
|
+
else
|
45
|
+
super(ColorizedString[progname_or_msg].yellow)
|
46
|
+
end
|
17
47
|
end
|
18
48
|
|
19
|
-
|
20
|
-
|
49
|
+
sig {
|
50
|
+
override.params(
|
51
|
+
progname_or_msg: T.untyped,
|
52
|
+
block: T.nilable(T.proc.returns(T.untyped))
|
53
|
+
).void
|
54
|
+
}
|
55
|
+
def fatal(progname_or_msg, &block)
|
56
|
+
if block
|
57
|
+
super(progname_or_msg) { ColorizedString[block.call].red }
|
58
|
+
else
|
59
|
+
super(ColorizedString[progname_or_msg].red)
|
60
|
+
end
|
21
61
|
end
|
22
62
|
|
23
63
|
# adhere to the "CLI" interface
|
24
|
-
|
25
|
-
|
64
|
+
sig {
|
65
|
+
params(
|
66
|
+
out: T.any(IO, StringIO),
|
67
|
+
err: T.any(IO, StringIO),
|
68
|
+
block: T.proc.void
|
69
|
+
).void
|
70
|
+
}
|
71
|
+
def with_pipes(out = STDOUT, err = STDERR, &block)
|
72
|
+
previous_logdev = @logdev&.dev || STDERR
|
26
73
|
reopen(err)
|
27
74
|
yield
|
28
75
|
ensure
|
29
76
|
reopen(previous_logdev)
|
30
77
|
end
|
31
78
|
|
79
|
+
sig { returns(T.nilable(Process::Status)) }
|
32
80
|
def last_status
|
33
81
|
nil
|
34
82
|
end
|
data/lib/kuby/cli_base.rb
CHANGED
@@ -1,24 +1,39 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
|
+
|
2
3
|
require 'open3'
|
3
4
|
require 'thread'
|
4
5
|
|
5
6
|
module Kuby
|
6
7
|
class CLIBase
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig { returns(T.nilable(Process::Status)) }
|
7
11
|
def last_status
|
8
12
|
Thread.current[status_key]
|
9
13
|
end
|
10
14
|
|
15
|
+
sig { params(block: T.proc.params(cmd: String).void).void }
|
11
16
|
def before_execute(&block)
|
17
|
+
@before_execute = T.let(@before_execute, T.nilable(T::Array[T.proc.params(cmd: String).void]))
|
12
18
|
@before_execute ||= []
|
13
19
|
@before_execute << block
|
14
20
|
end
|
15
21
|
|
22
|
+
sig { params(block: T.proc.params(cmd: String).void).void }
|
16
23
|
def after_execute(&block)
|
24
|
+
@after_execute = T.let(@after_execute, T.nilable(T::Array[T.proc.params(cmd: String).void]))
|
17
25
|
@after_execute ||= []
|
18
26
|
@after_execute << block
|
19
27
|
end
|
20
28
|
|
21
|
-
|
29
|
+
sig {
|
30
|
+
params(
|
31
|
+
out: T.any(IO, StringIO),
|
32
|
+
err: T.any(IO, StringIO),
|
33
|
+
block: T.proc.void
|
34
|
+
).void
|
35
|
+
}
|
36
|
+
def with_pipes(out = STDOUT, err = STDERR, &block)
|
22
37
|
previous_stdout = self.stdout
|
23
38
|
previous_stderr = self.stderr
|
24
39
|
self.stdout = out
|
@@ -29,29 +44,39 @@ module Kuby
|
|
29
44
|
self.stderr = previous_stderr
|
30
45
|
end
|
31
46
|
|
47
|
+
sig { returns(T.nilable(T.any(IO, StringIO))) }
|
32
48
|
def stdout
|
33
49
|
Thread.current[stdout_key] || STDOUT
|
34
50
|
end
|
35
51
|
|
52
|
+
sig { params(new_stdout: T.nilable(T.any(IO, StringIO))).void }
|
36
53
|
def stdout=(new_stdout)
|
37
54
|
Thread.current[stdout_key] = new_stdout
|
38
55
|
end
|
39
56
|
|
57
|
+
sig { returns(T.nilable(T.any(IO, StringIO))) }
|
40
58
|
def stderr
|
41
59
|
Thread.current[stderr_key] || STDERR
|
42
60
|
end
|
43
61
|
|
62
|
+
sig { params(new_stderr: T.nilable(T.any(IO, StringIO))).void }
|
44
63
|
def stderr=(new_stderr)
|
45
64
|
Thread.current[stderr_key] = new_stderr
|
46
65
|
end
|
47
66
|
|
48
67
|
private
|
49
68
|
|
50
|
-
|
69
|
+
sig {
|
70
|
+
params(
|
71
|
+
cmd: T::Array[String],
|
72
|
+
block: T.proc.params(stdin: IO).void
|
73
|
+
).void
|
74
|
+
}
|
75
|
+
def open3_w(cmd, &block)
|
51
76
|
run_before_callbacks(cmd)
|
52
77
|
cmd_s = cmd.join(' ')
|
53
78
|
|
54
|
-
Open3.popen3(
|
79
|
+
Open3.popen3(cmd_s) do |p_stdin, p_stdout, p_stderr, wait_thread|
|
55
80
|
Thread.new(stdout) do |t_stdout|
|
56
81
|
begin
|
57
82
|
p_stdout.each { |line| t_stdout.puts(line) }
|
@@ -66,21 +91,23 @@ module Kuby
|
|
66
91
|
end
|
67
92
|
end
|
68
93
|
|
69
|
-
yield(p_stdin)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
94
|
+
yield(p_stdin)
|
95
|
+
|
96
|
+
p_stdin.close
|
97
|
+
self.last_status = T.cast(wait_thread.value, Process::Status)
|
98
|
+
run_after_callbacks(cmd)
|
99
|
+
wait_thread.join
|
75
100
|
end
|
76
101
|
end
|
77
102
|
|
103
|
+
sig { params(cmd: T::Array[String]).void }
|
78
104
|
def execc(cmd)
|
79
105
|
run_before_callbacks(cmd)
|
80
106
|
cmd_s = cmd.join(' ')
|
81
107
|
exec(cmd_s)
|
82
108
|
end
|
83
109
|
|
110
|
+
sig { params(cmd: T::Array[String]).void }
|
84
111
|
def systemm(cmd)
|
85
112
|
if stdout == STDOUT && stderr == STDERR
|
86
113
|
systemm_default(cmd)
|
@@ -89,6 +116,7 @@ module Kuby
|
|
89
116
|
end
|
90
117
|
end
|
91
118
|
|
119
|
+
sig { params(cmd: T::Array[String]).void }
|
92
120
|
def systemm_default(cmd)
|
93
121
|
run_before_callbacks(cmd)
|
94
122
|
cmd_s = cmd.join(' ')
|
@@ -98,6 +126,7 @@ module Kuby
|
|
98
126
|
end
|
99
127
|
end
|
100
128
|
|
129
|
+
sig { params(cmd: T::Array[String]).void }
|
101
130
|
def systemm_open3(cmd)
|
102
131
|
run_before_callbacks(cmd)
|
103
132
|
cmd_s = cmd.join(' ')
|
@@ -118,12 +147,14 @@ module Kuby
|
|
118
147
|
end
|
119
148
|
|
120
149
|
p_stdin.close
|
121
|
-
self.last_status = wait_thread.value
|
150
|
+
self.last_status = T.cast(wait_thread.value, Process::Status)
|
122
151
|
run_after_callbacks(cmd)
|
123
152
|
wait_thread.join
|
124
153
|
end
|
125
154
|
end
|
126
155
|
|
156
|
+
|
157
|
+
sig { params(cmd: T::Array[String]).returns(String) }
|
127
158
|
def backticks(cmd)
|
128
159
|
if stdout == STDOUT && stderr == STDERR
|
129
160
|
backticks_default(cmd)
|
@@ -132,6 +163,7 @@ module Kuby
|
|
132
163
|
end
|
133
164
|
end
|
134
165
|
|
166
|
+
sig { params(cmd: T::Array[String]).returns(String) }
|
135
167
|
def backticks_default(cmd)
|
136
168
|
run_before_callbacks(cmd)
|
137
169
|
cmd_s = cmd.join(' ')
|
@@ -141,6 +173,7 @@ module Kuby
|
|
141
173
|
end
|
142
174
|
end
|
143
175
|
|
176
|
+
sig { params(cmd: T::Array[String]).returns(String) }
|
144
177
|
def backticks_open3(cmd)
|
145
178
|
run_before_callbacks(cmd)
|
146
179
|
cmd_s = cmd.join(' ')
|
@@ -162,7 +195,7 @@ module Kuby
|
|
162
195
|
end
|
163
196
|
|
164
197
|
p_stdin.close
|
165
|
-
self.last_status = wait_thread.value
|
198
|
+
self.last_status = T.cast(wait_thread.value, Process::Status)
|
166
199
|
run_after_callbacks(cmd)
|
167
200
|
wait_thread.join
|
168
201
|
end
|
@@ -170,26 +203,32 @@ module Kuby
|
|
170
203
|
result.string
|
171
204
|
end
|
172
205
|
|
206
|
+
sig { params(cmd: T::Array[String]).void }
|
173
207
|
def run_before_callbacks(cmd)
|
174
208
|
(@before_execute || []).each { |cb| cb.call(cmd) }
|
175
209
|
end
|
176
210
|
|
211
|
+
sig { params(cmd: T::Array[String]).void }
|
177
212
|
def run_after_callbacks(cmd)
|
178
213
|
(@after_execute || []).each { |cb| cb.call(cmd, last_status) }
|
179
214
|
end
|
180
215
|
|
216
|
+
sig { params(status: Process::Status).void }
|
181
217
|
def last_status=(status)
|
182
218
|
Thread.current[status_key] = status
|
183
219
|
end
|
184
220
|
|
221
|
+
sig { returns(Symbol) }
|
185
222
|
def status_key
|
186
223
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
187
224
|
end
|
188
225
|
|
226
|
+
sig { returns(Symbol) }
|
189
227
|
def stdout_key
|
190
228
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
191
229
|
end
|
192
230
|
|
231
|
+
sig { returns(Symbol) }
|
193
232
|
def stderr_key
|
194
233
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
195
234
|
end
|
data/lib/kuby/commands.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
# typed:
|
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
|
|
data/lib/kuby/definition.rb
CHANGED
@@ -1,12 +1,24 @@
|
|
1
|
-
# typed:
|
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
|
data/lib/kuby/dev_setup.rb
CHANGED
@@ -1,19 +1,34 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
|
+
|
2
3
|
module Kuby
|
3
4
|
class Spinner
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
|
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
|
data/lib/kuby/docker/cli.rb
CHANGED
@@ -35,13 +35,13 @@ module Kuby
|
|
35
35
|
executable, 'login', url, '--username', username, '--password-stdin'
|
36
36
|
]
|
37
37
|
|
38
|
-
open3_w(
|
38
|
+
open3_w(cmd) do |stdin, _wait_threads|
|
39
39
|
stdin.puts(password)
|
40
40
|
end
|
41
41
|
|
42
|
-
unless last_status.success?
|
42
|
+
unless T.must(last_status).success?
|
43
43
|
raise LoginError, 'build failed: docker command exited with '\
|
44
|
-
"status code #{last_status.exitstatus}"
|
44
|
+
"status code #{T.must(last_status).exitstatus}"
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -72,13 +72,13 @@ module Kuby
|
|
72
72
|
'-f-', '.'
|
73
73
|
]
|
74
74
|
|
75
|
-
open3_w(
|
75
|
+
open3_w(cmd) do |stdin, _wait_threads|
|
76
76
|
stdin.puts(dockerfile.to_s)
|
77
77
|
end
|
78
78
|
|
79
|
-
unless last_status.success?
|
79
|
+
unless T.must(last_status).success?
|
80
80
|
raise BuildError, 'build failed: docker command exited with '\
|
81
|
-
"status code #{last_status.exitstatus}"
|
81
|
+
"status code #{T.must(last_status).exitstatus}"
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -124,9 +124,9 @@ module Kuby
|
|
124
124
|
executable, 'push', "#{image_url}:#{tag}"
|
125
125
|
])
|
126
126
|
|
127
|
-
unless last_status.success?
|
127
|
+
unless T.must(last_status).success?
|
128
128
|
raise PushError, 'push failed: docker command exited with '\
|
129
|
-
"status code #{last_status.exitstatus}"
|
129
|
+
"status code #{T.must(last_status).exitstatus}"
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -136,9 +136,9 @@ module Kuby
|
|
136
136
|
executable, 'pull', "#{image_url}:#{tag}"
|
137
137
|
])
|
138
138
|
|
139
|
-
unless last_status.success?
|
139
|
+
unless T.must(last_status).success?
|
140
140
|
raise PullError, 'pull failed: docker command exited with '\
|
141
|
-
"status code #{last_status.exitstatus}"
|
141
|
+
"status code #{T.must(last_status).exitstatus}"
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
data/lib/kuby/docker/dev_spec.rb
CHANGED
@@ -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|
|
data/lib/kuby/kubernetes/spec.rb
CHANGED
@@ -18,13 +18,28 @@ module Kuby
|
|
18
18
|
|
19
19
|
def provider(provider_name = nil, &block)
|
20
20
|
if provider_name
|
21
|
-
|
22
|
-
|
21
|
+
provider_klass = Kuby.providers[provider_name]
|
22
|
+
|
23
|
+
unless provider_klass
|
24
|
+
begin
|
25
|
+
# attempt to auto-require
|
26
|
+
require "kuby/#{provider_name}"
|
27
|
+
provider_klass = Kuby.providers[provider_name]
|
28
|
+
rescue LoadError
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if provider_klass
|
33
|
+
if !@provider || !@provider.is_a?(provider_klass)
|
34
|
+
@provider = provider_klass.new(environment)
|
35
|
+
end
|
36
|
+
|
23
37
|
@provider.configure(&block)
|
24
38
|
else
|
25
39
|
msg = if provider_name
|
26
40
|
"no provider registered with name #{provider_name}, "\
|
27
|
-
'do you need to add a gem to your Gemfile
|
41
|
+
'do you need to add a gem to your Gemfile and/or a '\
|
42
|
+
'require statement to your Kuby config?'
|
28
43
|
else
|
29
44
|
'no provider configured'
|
30
45
|
end
|
data/lib/kuby/plugin_registry.rb
CHANGED
@@ -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('#{
|
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
|
|
@@ -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
|
data/lib/kuby/version.rb
CHANGED
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.
|
4
|
+
version: 0.11.7
|
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-
|
11
|
+
date: 2020-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|