kuby-core 0.9.0 → 0.11.1
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 +32 -0
- data/Gemfile +1 -0
- data/README.md +4 -2
- data/kuby-core.gemspec +2 -1
- data/lib/kuby-core.rb +1 -0
- data/lib/kuby.rb +14 -0
- data/lib/kuby/basic_logger.rb +1 -0
- data/lib/kuby/cli_base.rb +53 -4
- data/lib/kuby/commands.rb +29 -4
- data/lib/kuby/definition.rb +1 -0
- data/lib/kuby/dev_setup.rb +1 -0
- data/lib/kuby/docker.rb +3 -0
- data/lib/kuby/docker/alpine.rb +16 -12
- data/lib/kuby/docker/assets_phase.rb +5 -0
- data/lib/kuby/docker/bundler_phase.rb +36 -2
- data/lib/kuby/docker/cli.rb +47 -2
- data/lib/kuby/docker/copy_phase.rb +11 -3
- data/lib/kuby/docker/credentials.rb +1 -0
- data/lib/kuby/docker/debian.rb +14 -10
- data/lib/kuby/docker/dev_spec.rb +82 -18
- data/lib/kuby/docker/distro.rb +43 -0
- data/lib/kuby/docker/dockerfile.rb +67 -19
- data/lib/kuby/docker/errors.rb +9 -0
- data/lib/kuby/docker/inline_layer.rb +7 -0
- data/lib/kuby/docker/layer.rb +11 -0
- data/lib/kuby/docker/layer_stack.rb +43 -6
- data/lib/kuby/docker/local_tags.rb +23 -2
- data/lib/kuby/docker/metadata.rb +35 -7
- data/lib/kuby/docker/package_list.rb +22 -3
- data/lib/kuby/docker/package_phase.rb +25 -5
- data/lib/kuby/docker/packages.rb +1 -0
- data/lib/kuby/docker/packages/managed_package.rb +20 -2
- data/lib/kuby/docker/packages/nodejs.rb +8 -0
- data/lib/kuby/docker/packages/package.rb +15 -1
- data/lib/kuby/docker/packages/simple_managed_package.rb +10 -1
- data/lib/kuby/docker/packages/yarn.rb +14 -0
- data/lib/kuby/docker/remote_tags.rb +21 -2
- data/lib/kuby/docker/setup_phase.rb +35 -4
- data/lib/kuby/docker/spec.rb +89 -13
- data/lib/kuby/docker/tags.rb +37 -2
- data/lib/kuby/docker/timestamp_tag.rb +14 -2
- data/lib/kuby/docker/webserver_phase.rb +41 -6
- data/lib/kuby/docker/yarn_phase.rb +5 -0
- data/lib/kuby/environment.rb +4 -0
- data/lib/kuby/kubernetes.rb +1 -0
- data/lib/kuby/kubernetes/deploy_task.rb +1 -0
- data/lib/kuby/kubernetes/deployer.rb +8 -4
- data/lib/kuby/kubernetes/docker_config.rb +1 -0
- data/lib/kuby/kubernetes/docker_desktop_provider.rb +1 -0
- data/lib/kuby/kubernetes/errors.rb +1 -0
- data/lib/kuby/kubernetes/manifest.rb +1 -0
- data/lib/kuby/kubernetes/provider.rb +1 -0
- data/lib/kuby/kubernetes/registry_secret.rb +1 -0
- data/lib/kuby/kubernetes/spec.rb +1 -0
- data/lib/kuby/middleware.rb +1 -0
- data/lib/kuby/middleware/health_check.rb +1 -0
- data/lib/kuby/plugin.rb +1 -0
- data/lib/kuby/plugin_registry.rb +1 -0
- data/lib/kuby/plugins.rb +1 -0
- data/lib/kuby/plugins/nginx_ingress.rb +1 -0
- data/lib/kuby/plugins/rails_app.rb +1 -0
- data/lib/kuby/plugins/rails_app/asset_copy_task.rb +1 -0
- data/lib/kuby/plugins/rails_app/assets.rb +1 -0
- data/lib/kuby/plugins/rails_app/database.rb +10 -9
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +45 -32
- data/lib/kuby/plugins/rails_app/mysql.rb +1 -3
- data/lib/kuby/plugins/rails_app/plugin.rb +13 -4
- data/lib/kuby/plugins/rails_app/postgres.rb +1 -0
- data/lib/kuby/plugins/rails_app/rewrite_db_config.rb +1 -0
- data/lib/kuby/plugins/rails_app/sqlite.rb +1 -0
- data/lib/kuby/rails_commands.rb +14 -19
- data/lib/kuby/railtie.rb +1 -0
- data/lib/kuby/tasks.rb +3 -1
- data/lib/kuby/trailing_hash.rb +5 -3
- data/lib/kuby/version.rb +3 -1
- data/spec/docker/metadata_spec.rb +1 -0
- data/spec/docker/spec_spec.rb +37 -0
- data/spec/docker/timestamp_tag_spec.rb +1 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +1 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/app/helpers/application_helper.rb +1 -0
- data/spec/dummy/app/jobs/application_job.rb +1 -0
- data/spec/dummy/app/mailers/application_mailer.rb +1 -0
- data/spec/dummy/app/models/application_record.rb +1 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/boot.rb +1 -0
- data/spec/dummy/config/environment.rb +1 -0
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/production.rb +1 -0
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +1 -0
- data/spec/dummy/config/initializers/assets.rb +1 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +1 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +1 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +1 -0
- data/spec/dummy/config/initializers/mime_types.rb +1 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +1 -0
- data/spec/dummy/config/puma.rb +1 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/dummy/config/spring.rb +1 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/dummy/test/application_system_test_case.rb +1 -0
- data/spec/dummy/test/channels/application_cable/connection_test.rb +1 -0
- data/spec/dummy/test/test_helper.rb +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/docker/fake_cli.rb +1 -0
- data/spec/support/docker/remote/fake_client.rb +1 -0
- data/spec/trailing_hash_spec.rb +2 -0
- metadata +20 -4
|
@@ -1,28 +1,43 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
require 'digest'
|
|
2
4
|
|
|
3
5
|
module Kuby
|
|
4
6
|
module Docker
|
|
5
7
|
class Dockerfile
|
|
8
|
+
extend T::Sig
|
|
9
|
+
|
|
6
10
|
class Command
|
|
11
|
+
extend T::Sig
|
|
12
|
+
|
|
13
|
+
sig { returns(T::Array[T.any(String, Integer)]) }
|
|
7
14
|
attr_reader :args
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
sig { params(args: T::Array[T.any(String, Integer)]).void }
|
|
17
|
+
def initialize(args)
|
|
10
18
|
@args = args
|
|
11
19
|
end
|
|
12
20
|
|
|
21
|
+
sig { returns(String) }
|
|
13
22
|
def to_s
|
|
14
23
|
args.join(' ')
|
|
15
24
|
end
|
|
16
25
|
end
|
|
17
26
|
|
|
18
27
|
class From < Command
|
|
19
|
-
|
|
28
|
+
sig { returns(String) }
|
|
29
|
+
attr_reader :image_url
|
|
30
|
+
|
|
31
|
+
sig { returns(T.nilable(String)) }
|
|
32
|
+
attr_reader :as
|
|
20
33
|
|
|
34
|
+
sig { params(image_url: String, as: T.nilable(String)).void }
|
|
21
35
|
def initialize(image_url, as: nil)
|
|
22
36
|
@image_url = image_url
|
|
23
37
|
@as = as
|
|
24
38
|
end
|
|
25
39
|
|
|
40
|
+
sig { returns(String) }
|
|
26
41
|
def to_s
|
|
27
42
|
str = "FROM #{image_url}"
|
|
28
43
|
str << " AS #{as}" if as
|
|
@@ -31,26 +46,38 @@ module Kuby
|
|
|
31
46
|
end
|
|
32
47
|
|
|
33
48
|
class Workdir < Command
|
|
49
|
+
sig { returns(String) }
|
|
34
50
|
def to_s; "WORKDIR #{super}"; end
|
|
35
51
|
end
|
|
36
52
|
|
|
37
53
|
class Env < Command
|
|
54
|
+
sig { returns(String) }
|
|
38
55
|
def to_s; "ENV #{super}"; end
|
|
39
56
|
end
|
|
40
57
|
|
|
41
58
|
class Run < Command
|
|
59
|
+
sig { returns(String) }
|
|
42
60
|
def to_s; "RUN #{super}"; end
|
|
43
61
|
end
|
|
44
62
|
|
|
45
63
|
class Copy < Command
|
|
46
|
-
|
|
64
|
+
sig { returns(String) }
|
|
65
|
+
attr_reader :source
|
|
47
66
|
|
|
67
|
+
sig { returns(String) }
|
|
68
|
+
attr_reader :dest
|
|
69
|
+
|
|
70
|
+
sig { returns(T.nilable(String)) }
|
|
71
|
+
attr_reader :from
|
|
72
|
+
|
|
73
|
+
sig { params(source: String, dest: String, from: T.nilable(String)).void }
|
|
48
74
|
def initialize(source, dest, from: nil)
|
|
49
75
|
@source = source
|
|
50
76
|
@dest = dest
|
|
51
77
|
@from = from
|
|
52
78
|
end
|
|
53
79
|
|
|
80
|
+
sig { returns(String) }
|
|
54
81
|
def to_s
|
|
55
82
|
cmd = ['COPY']
|
|
56
83
|
cmd << "--from=#{from}" if from
|
|
@@ -60,72 +87,92 @@ module Kuby
|
|
|
60
87
|
end
|
|
61
88
|
|
|
62
89
|
class Expose < Command
|
|
90
|
+
sig { returns(String) }
|
|
63
91
|
def to_s; "EXPOSE #{super}"; end
|
|
64
92
|
end
|
|
65
93
|
|
|
66
94
|
class Cmd < Command
|
|
95
|
+
sig { returns(String) }
|
|
67
96
|
def to_s; "CMD #{super}"; end
|
|
68
97
|
end
|
|
69
98
|
|
|
70
99
|
class Arg < Command
|
|
100
|
+
sig { returns(String) }
|
|
71
101
|
def to_s; "ARG #{super}"; end
|
|
72
102
|
end
|
|
73
103
|
|
|
74
|
-
|
|
104
|
+
sig { returns(T::Array[Command]) }
|
|
105
|
+
attr_reader :commands
|
|
106
|
+
|
|
107
|
+
sig { returns(Integer) }
|
|
108
|
+
attr_reader :cursor
|
|
75
109
|
|
|
110
|
+
sig { void }
|
|
76
111
|
def initialize
|
|
77
|
-
@commands = []
|
|
78
|
-
@cursor = 0
|
|
112
|
+
@commands = T.let([], T::Array[Command])
|
|
113
|
+
@cursor = T.let(0, Integer)
|
|
79
114
|
end
|
|
80
115
|
|
|
81
|
-
|
|
82
|
-
|
|
116
|
+
sig { params(image_url: String, as: T.nilable(String)).void }
|
|
117
|
+
def from(image_url, as: nil)
|
|
118
|
+
add From.new(image_url, as: as)
|
|
83
119
|
end
|
|
84
120
|
|
|
121
|
+
sig { params(args: String).void }
|
|
85
122
|
def workdir(*args)
|
|
86
|
-
add Workdir.new(
|
|
123
|
+
add Workdir.new(args)
|
|
87
124
|
end
|
|
88
125
|
|
|
126
|
+
sig { params(args: String).void }
|
|
89
127
|
def env(*args)
|
|
90
|
-
add Env.new(
|
|
128
|
+
add Env.new(args)
|
|
91
129
|
end
|
|
92
130
|
|
|
131
|
+
sig { params(args: String).void }
|
|
93
132
|
def arg(*args)
|
|
94
|
-
add Arg.new(
|
|
133
|
+
add Arg.new(args)
|
|
95
134
|
end
|
|
96
135
|
|
|
136
|
+
sig { params(args: String).void }
|
|
97
137
|
def run(*args)
|
|
98
|
-
add Run.new(
|
|
138
|
+
add Run.new(args)
|
|
99
139
|
end
|
|
100
140
|
|
|
101
|
-
|
|
102
|
-
|
|
141
|
+
sig { params(source: String, dest: String, from: T.nilable(String)).void }
|
|
142
|
+
def copy(source, dest, from: nil)
|
|
143
|
+
add Copy.new(source, dest, from: from)
|
|
103
144
|
end
|
|
104
145
|
|
|
105
|
-
|
|
106
|
-
|
|
146
|
+
sig { params(port: Integer).void }
|
|
147
|
+
def expose(port)
|
|
148
|
+
add Expose.new([port])
|
|
107
149
|
end
|
|
108
150
|
|
|
151
|
+
sig { params(args: String).void }
|
|
109
152
|
def cmd(*args)
|
|
110
|
-
add Cmd.new(
|
|
153
|
+
add Cmd.new(args)
|
|
111
154
|
end
|
|
112
155
|
|
|
156
|
+
sig { returns(String) }
|
|
113
157
|
def to_s
|
|
114
158
|
# ensure trailing newline
|
|
115
159
|
"#{commands.map(&:to_s).join("\n")}\n"
|
|
116
160
|
end
|
|
117
161
|
|
|
162
|
+
sig { returns(String) }
|
|
118
163
|
def checksum
|
|
119
164
|
Digest::SHA256.hexdigest(to_s)
|
|
120
165
|
end
|
|
121
166
|
|
|
167
|
+
sig { returns(T::Array[Integer]) }
|
|
122
168
|
def exposed_ports
|
|
123
169
|
commands
|
|
124
170
|
.select { |c| c.is_a?(Expose) }
|
|
125
|
-
.map { |c| c.args.first }
|
|
171
|
+
.map { |c| T.cast(c.args.first, Integer) }
|
|
126
172
|
end
|
|
127
173
|
|
|
128
|
-
|
|
174
|
+
sig { params(pos: Integer, block: T.proc.void).void }
|
|
175
|
+
def insert_at(pos, &block)
|
|
129
176
|
@cursor = pos
|
|
130
177
|
yield
|
|
131
178
|
ensure
|
|
@@ -134,6 +181,7 @@ module Kuby
|
|
|
134
181
|
|
|
135
182
|
private
|
|
136
183
|
|
|
184
|
+
sig { params(cmd: Command).void }
|
|
137
185
|
def add(cmd)
|
|
138
186
|
commands.insert(cursor, cmd)
|
|
139
187
|
@cursor += 1
|
data/lib/kuby/docker/errors.rb
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class BuildError < StandardError; end
|
|
4
6
|
class PushError < StandardError; end
|
|
7
|
+
class PullError < StandardError; end
|
|
5
8
|
class LoginError < StandardError; end
|
|
6
9
|
|
|
7
10
|
class MissingTagError < StandardError
|
|
11
|
+
extend T::Sig
|
|
12
|
+
|
|
13
|
+
sig { returns(String) }
|
|
8
14
|
attr_reader :tag
|
|
9
15
|
|
|
16
|
+
sig { params(tag: String).void }
|
|
10
17
|
def initialize(tag)
|
|
11
18
|
@tag = tag
|
|
19
|
+
@message = T.let(@message, T.nilable(String))
|
|
12
20
|
end
|
|
13
21
|
|
|
22
|
+
sig { returns(String) }
|
|
14
23
|
def message
|
|
15
24
|
@message ||= "Could not find tag '#{tag}'."
|
|
16
25
|
end
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class InlineLayer < Layer
|
|
6
|
+
extend T::Sig
|
|
7
|
+
|
|
8
|
+
sig { returns(T.proc.params(df: Dockerfile).void) }
|
|
4
9
|
attr_reader :block
|
|
5
10
|
|
|
11
|
+
sig { params(block: T.proc.params(df: Dockerfile).void).void }
|
|
6
12
|
def initialize(block)
|
|
7
13
|
@block = block
|
|
8
14
|
end
|
|
9
15
|
|
|
16
|
+
sig { override.params(dockerfile: Dockerfile).void }
|
|
10
17
|
def apply_to(dockerfile)
|
|
11
18
|
block.call(dockerfile)
|
|
12
19
|
end
|
data/lib/kuby/docker/layer.rb
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class Layer
|
|
6
|
+
extend T::Sig
|
|
7
|
+
extend T::Helpers
|
|
8
|
+
|
|
9
|
+
abstract!
|
|
10
|
+
|
|
11
|
+
sig { returns(Environment) }
|
|
4
12
|
attr_reader :environment
|
|
5
13
|
|
|
14
|
+
sig { params(environment: Environment).void }
|
|
6
15
|
def initialize(environment)
|
|
7
16
|
@environment = environment
|
|
8
17
|
end
|
|
9
18
|
|
|
19
|
+
sig { params(dockerfile: Dockerfile).void }
|
|
10
20
|
def apply_to(dockerfile)
|
|
11
21
|
raise NotImplementedError,
|
|
12
22
|
"#{__method__} must be defined in derived classes"
|
|
@@ -14,6 +24,7 @@ module Kuby
|
|
|
14
24
|
|
|
15
25
|
private
|
|
16
26
|
|
|
27
|
+
sig { returns(Metadata) }
|
|
17
28
|
def metadata
|
|
18
29
|
environment.docker.metadata
|
|
19
30
|
end
|
|
@@ -1,20 +1,46 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class LayerStack
|
|
6
|
+
extend T::Sig
|
|
7
|
+
extend T::Generic
|
|
8
|
+
|
|
9
|
+
Elem = type_member(fixed: Layer)
|
|
10
|
+
|
|
4
11
|
include Enumerable
|
|
5
12
|
|
|
6
|
-
|
|
13
|
+
sig { returns(T::Array[Symbol]) }
|
|
14
|
+
attr_reader :stack
|
|
15
|
+
|
|
16
|
+
sig { returns(T::Hash[Symbol, Layer]) }
|
|
17
|
+
attr_reader :layers
|
|
7
18
|
|
|
19
|
+
sig { void }
|
|
8
20
|
def initialize
|
|
9
|
-
@stack = []
|
|
10
|
-
@layers = {}
|
|
21
|
+
@stack = T.let([], T::Array[Symbol])
|
|
22
|
+
@layers = T.let({}, T::Hash[Symbol, Layer])
|
|
11
23
|
end
|
|
12
24
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
sig {
|
|
26
|
+
override.params(
|
|
27
|
+
block: T.nilable(T.proc.params(layer: Layer).void)
|
|
28
|
+
)
|
|
29
|
+
.void
|
|
30
|
+
}
|
|
31
|
+
def each(&block)
|
|
32
|
+
return to_enum(T.must(__method__)) unless block_given?
|
|
33
|
+
@stack.each { |name| yield T.must(layers[name]) }
|
|
16
34
|
end
|
|
17
35
|
|
|
36
|
+
sig {
|
|
37
|
+
params(
|
|
38
|
+
name: Symbol,
|
|
39
|
+
layer: T.nilable(Layer),
|
|
40
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
|
41
|
+
)
|
|
42
|
+
.void
|
|
43
|
+
}
|
|
18
44
|
def use(name, layer = nil, &block)
|
|
19
45
|
stack << name
|
|
20
46
|
|
|
@@ -27,6 +53,15 @@ module Kuby
|
|
|
27
53
|
end
|
|
28
54
|
end
|
|
29
55
|
|
|
56
|
+
sig {
|
|
57
|
+
params(
|
|
58
|
+
name: Symbol,
|
|
59
|
+
layer: T.nilable(T.any(Layer, T::Hash[Symbol, T.untyped])),
|
|
60
|
+
options: T::Hash[Symbol, T.untyped],
|
|
61
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
|
62
|
+
)
|
|
63
|
+
.void
|
|
64
|
+
}
|
|
30
65
|
def insert(name, layer = nil, options = {}, &block)
|
|
31
66
|
# this is truly gross but it's the only way I can think of to be able
|
|
32
67
|
# to call insert these two ways:
|
|
@@ -59,11 +94,13 @@ module Kuby
|
|
|
59
94
|
end
|
|
60
95
|
end
|
|
61
96
|
|
|
97
|
+
sig { params(name: Symbol).void }
|
|
62
98
|
def delete(name)
|
|
63
99
|
stack.delete(name)
|
|
64
100
|
layers.delete(name)
|
|
65
101
|
end
|
|
66
102
|
|
|
103
|
+
sig { params(name: Symbol).returns(T::Boolean) }
|
|
67
104
|
def includes?(name)
|
|
68
105
|
layers.include?(name)
|
|
69
106
|
end
|
|
@@ -1,18 +1,37 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class LocalTags
|
|
4
|
-
|
|
6
|
+
extend T::Sig
|
|
7
|
+
|
|
8
|
+
sig { returns CLI }
|
|
9
|
+
attr_reader :cli
|
|
5
10
|
|
|
11
|
+
sig { returns(Metadata) }
|
|
12
|
+
attr_reader :metadata
|
|
13
|
+
|
|
14
|
+
sig {
|
|
15
|
+
params(
|
|
16
|
+
cli: CLI,
|
|
17
|
+
metadata: Metadata
|
|
18
|
+
)
|
|
19
|
+
.void
|
|
20
|
+
}
|
|
6
21
|
def initialize(cli, metadata)
|
|
7
22
|
@cli = cli
|
|
8
23
|
@metadata = metadata
|
|
24
|
+
|
|
25
|
+
@latest_timestamp_tag = T.let(@latest_timestamp_tag, T.nilable(TimestampTag))
|
|
9
26
|
end
|
|
10
27
|
|
|
28
|
+
sig { returns(T::Array[String]) }
|
|
11
29
|
def tags
|
|
12
30
|
images = cli.images(metadata.image_url)
|
|
13
|
-
images.map { |image| image[:tag] }
|
|
31
|
+
images.map { |image| T.must(image[:tag]) }
|
|
14
32
|
end
|
|
15
33
|
|
|
34
|
+
sig { returns(T::Array[String]) }
|
|
16
35
|
def latest_tags
|
|
17
36
|
# find "latest" tag
|
|
18
37
|
images = cli.images(metadata.image_url)
|
|
@@ -30,10 +49,12 @@ module Kuby
|
|
|
30
49
|
end
|
|
31
50
|
end
|
|
32
51
|
|
|
52
|
+
sig { returns(T::Array[TimestampTag]) }
|
|
33
53
|
def timestamp_tags
|
|
34
54
|
tags.map { |t| TimestampTag.try_parse(t) }.compact
|
|
35
55
|
end
|
|
36
56
|
|
|
57
|
+
sig { returns(T.nilable(TimestampTag)) }
|
|
37
58
|
def latest_timestamp_tag
|
|
38
59
|
@latest_timestamp_tag ||= timestamp_tags.sort.last
|
|
39
60
|
end
|
data/lib/kuby/docker/metadata.rb
CHANGED
|
@@ -1,51 +1,76 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
require 'uri'
|
|
2
4
|
|
|
3
5
|
module Kuby
|
|
4
6
|
module Docker
|
|
5
7
|
class Metadata
|
|
8
|
+
extend T::Sig
|
|
9
|
+
|
|
6
10
|
DEFAULT_DISTRO = :debian
|
|
7
|
-
DEFAULT_REGISTRY_HOST = 'https://www.docker.com'.freeze
|
|
8
|
-
DEFAULT_REGISTRY_SCHEME = 'https'
|
|
9
|
-
LATEST_TAG = 'latest'
|
|
11
|
+
DEFAULT_REGISTRY_HOST = T.let('https://www.docker.com'.freeze, String)
|
|
12
|
+
DEFAULT_REGISTRY_SCHEME = T.let('https', String)
|
|
13
|
+
LATEST_TAG = T.let('latest'.freeze, String)
|
|
14
|
+
|
|
15
|
+
sig { params(image_url: String).void }
|
|
16
|
+
attr_writer :image_url
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
sig { returns(Environment) }
|
|
12
19
|
attr_reader :environment
|
|
13
20
|
|
|
21
|
+
sig { params(environment: Environment).void }
|
|
14
22
|
def initialize(environment)
|
|
15
23
|
@environment = environment
|
|
16
|
-
@tags = []
|
|
24
|
+
@tags = T.let([], T::Array[String])
|
|
25
|
+
|
|
26
|
+
@image_url = T.let(@image_url, T.nilable(String))
|
|
27
|
+
@image_host = T.let(@image_host, T.nilable(String))
|
|
28
|
+
@image_hostname = T.let(@image_hostname, T.nilable(String))
|
|
29
|
+
@image_repo = T.let(@image_repo, T.nilable(String))
|
|
30
|
+
@distro = T.let(@distro, T.nilable(Symbol))
|
|
31
|
+
@full_image_uri = T.let(@full_image_uri, T.nilable(URI::Generic))
|
|
32
|
+
@default_image_url = T.let(@default_image_url, T.nilable(String))
|
|
33
|
+
@default_tags = T.let(@default_tags, T.nilable(T::Array[String]))
|
|
17
34
|
end
|
|
18
35
|
|
|
36
|
+
sig { returns(String) }
|
|
19
37
|
def image_url
|
|
20
38
|
@image_url || default_image_url
|
|
21
39
|
end
|
|
22
40
|
|
|
41
|
+
sig { returns(String) }
|
|
23
42
|
def image_host
|
|
24
43
|
@image_host ||= "#{full_image_uri.scheme}://#{full_image_uri.host}"
|
|
25
44
|
end
|
|
26
45
|
|
|
46
|
+
sig { returns(String) }
|
|
27
47
|
def image_hostname
|
|
28
|
-
@image_hostname ||= URI(image_host).host
|
|
48
|
+
@image_hostname ||= T.must(URI(image_host).host)
|
|
29
49
|
end
|
|
30
50
|
|
|
51
|
+
sig { returns(String) }
|
|
31
52
|
def image_repo
|
|
32
|
-
@image_repo ||= full_image_uri.path.sub(/\A[\/]+/, '')
|
|
53
|
+
@image_repo ||= T.must(full_image_uri.path).sub(/\A[\/]+/, '')
|
|
33
54
|
end
|
|
34
55
|
|
|
56
|
+
sig { returns(T::Array[String]) }
|
|
35
57
|
def tags
|
|
36
58
|
@tags.empty? ? default_tags : @tags
|
|
37
59
|
end
|
|
38
60
|
|
|
61
|
+
sig { returns(Symbol) }
|
|
39
62
|
def distro
|
|
40
63
|
@distro || DEFAULT_DISTRO
|
|
41
64
|
end
|
|
42
65
|
|
|
66
|
+
sig { params(distro_name: Symbol).void }
|
|
43
67
|
def distro=(distro_name)
|
|
44
68
|
@distro = distro_name
|
|
45
69
|
end
|
|
46
70
|
|
|
47
71
|
private
|
|
48
72
|
|
|
73
|
+
sig { returns(URI::Generic) }
|
|
49
74
|
def full_image_uri
|
|
50
75
|
@full_image_uri ||= if image_url.include?('://')
|
|
51
76
|
URI.parse(image_url)
|
|
@@ -56,17 +81,20 @@ module Kuby
|
|
|
56
81
|
end
|
|
57
82
|
end
|
|
58
83
|
|
|
84
|
+
sig { returns(String) }
|
|
59
85
|
def default_image_url
|
|
60
86
|
# assuming dockerhub by not specifying full url
|
|
61
87
|
@default_image_url ||= environment.app_name.downcase
|
|
62
88
|
end
|
|
63
89
|
|
|
90
|
+
sig { returns(T::Array[String]) }
|
|
64
91
|
def default_tags
|
|
65
92
|
@default_tags ||= [
|
|
66
93
|
TimestampTag.new(Time.now).to_s, LATEST_TAG
|
|
67
94
|
]
|
|
68
95
|
end
|
|
69
96
|
|
|
97
|
+
sig { params(url: String).returns(URI::Generic) }
|
|
70
98
|
def parse_url(url)
|
|
71
99
|
uri = URI.parse(url)
|
|
72
100
|
return uri if uri.scheme
|