kuby-core 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/Gemfile +6 -2
  4. data/Rakefile +5 -3
  5. data/bin/tapioca +29 -0
  6. data/kuby-core.gemspec +9 -11
  7. data/lib/kuby/basic_logger.rb +34 -34
  8. data/lib/kuby/cli_base.rb +43 -43
  9. data/lib/kuby/commands.rb +94 -11
  10. data/lib/kuby/definition.rb +12 -12
  11. data/lib/kuby/dependable.rb +20 -0
  12. data/lib/kuby/dependency.rb +14 -0
  13. data/lib/kuby/docker/alpine.rb +10 -10
  14. data/lib/kuby/docker/app_image.rb +11 -11
  15. data/lib/kuby/docker/app_phase.rb +36 -0
  16. data/lib/kuby/docker/assets_phase.rb +2 -2
  17. data/lib/kuby/docker/bundler_phase.rb +42 -40
  18. data/lib/kuby/docker/cli.rb +71 -43
  19. data/lib/kuby/docker/copy_phase.rb +7 -7
  20. data/lib/kuby/docker/credentials.rb +1 -0
  21. data/lib/kuby/docker/debian.rb +10 -10
  22. data/lib/kuby/docker/distro.rb +13 -13
  23. data/lib/kuby/docker/docker_uri.rb +20 -20
  24. data/lib/kuby/docker/dockerfile.rb +48 -39
  25. data/lib/kuby/docker/image.rb +66 -54
  26. data/lib/kuby/docker/inline_layer.rb +4 -4
  27. data/lib/kuby/docker/layer.rb +6 -6
  28. data/lib/kuby/docker/layer_stack.rb +35 -35
  29. data/lib/kuby/docker/local_tags.rb +16 -16
  30. data/lib/kuby/docker/package_list.rb +16 -16
  31. data/lib/kuby/docker/package_phase.rb +16 -16
  32. data/lib/kuby/docker/packages/managed_package.rb +13 -13
  33. data/lib/kuby/docker/packages/nodejs.rb +5 -5
  34. data/lib/kuby/docker/packages/package.rb +8 -8
  35. data/lib/kuby/docker/packages/simple_managed_package.rb +7 -7
  36. data/lib/kuby/docker/packages/yarn.rb +6 -6
  37. data/lib/kuby/docker/remote_tags.rb +16 -16
  38. data/lib/kuby/docker/setup_phase.rb +18 -20
  39. data/lib/kuby/docker/spec.rb +93 -72
  40. data/lib/kuby/docker/timestamp_tag.rb +16 -11
  41. data/lib/kuby/docker/timestamped_image.rb +59 -40
  42. data/lib/kuby/docker/webserver_phase.rb +20 -20
  43. data/lib/kuby/docker/yarn_phase.rb +29 -5
  44. data/lib/kuby/docker.rb +2 -1
  45. data/lib/kuby/kubernetes/bare_metal_provider.rb +9 -9
  46. data/lib/kuby/kubernetes/deployer.rb +22 -10
  47. data/lib/kuby/kubernetes/docker_config.rb +1 -0
  48. data/lib/kuby/kubernetes/provider.rb +1 -0
  49. data/lib/kuby/kubernetes/spec.rb +47 -7
  50. data/lib/kuby/plugin.rb +22 -1
  51. data/lib/kuby/plugins/nginx_ingress.rb +8 -6
  52. data/lib/kuby/plugins/rails_app/assets.rb +16 -4
  53. data/lib/kuby/plugins/rails_app/assets_image.rb +17 -8
  54. data/lib/kuby/plugins/rails_app/crdb/plugin.rb +473 -0
  55. data/lib/kuby/plugins/rails_app/crdb.rb +9 -0
  56. data/lib/kuby/plugins/rails_app/database.rb +12 -8
  57. data/lib/kuby/plugins/rails_app/generators/kuby.rb +17 -16
  58. data/lib/kuby/plugins/rails_app/plugin.rb +29 -18
  59. data/lib/kuby/plugins/rails_app/sqlite.rb +7 -3
  60. data/lib/kuby/plugins/rails_app/tasks.rake +25 -12
  61. data/lib/kuby/plugins/rails_app.rb +1 -0
  62. data/lib/kuby/plugins/system.rb +16 -0
  63. data/lib/kuby/plugins.rb +1 -0
  64. data/lib/kuby/railtie.rb +31 -1
  65. data/lib/kuby/tasks.rb +72 -5
  66. data/lib/kuby/trailing_hash.rb +2 -2
  67. data/lib/kuby/utils/sem_ver/constraint.rb +68 -0
  68. data/lib/kuby/utils/sem_ver/constraint_set.rb +25 -0
  69. data/lib/kuby/utils/sem_ver/version.rb +49 -0
  70. data/lib/kuby/utils/sem_ver.rb +17 -0
  71. data/lib/kuby/utils/which.rb +65 -0
  72. data/lib/kuby/utils.rb +7 -1
  73. data/lib/kuby/version.rb +1 -1
  74. data/lib/kuby.rb +37 -2
  75. data/rbi/kuby-core.rbi +2128 -0
  76. data/spec/docker/spec_spec.rb +50 -26
  77. data/spec/dummy/app/channels/application_cable/channel.rb +2 -1
  78. data/spec/dummy/app/channels/application_cable/connection.rb +2 -1
  79. data/spec/dummy/app/controllers/application_controller.rb +2 -1
  80. data/spec/dummy/app/jobs/application_job.rb +2 -1
  81. data/spec/dummy/app/mailers/application_mailer.rb +2 -1
  82. data/spec/dummy/app/models/application_record.rb +2 -1
  83. data/spec/dummy/config/application.rb +2 -1
  84. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -1
  85. data/spec/dummy/config/routes.rb +2 -1
  86. data/spec/dummy/test/application_system_test_case.rb +2 -1
  87. data/spec/dummy/test/channels/application_cable/connection_test.rb +2 -1
  88. data/spec/spec_helper.rb +13 -1
  89. metadata +44 -39
  90. data/lib/kuby/plugins/rails_app/mysql.rb +0 -158
  91. data/lib/kuby/plugins/rails_app/postgres.rb +0 -163
@@ -2,23 +2,23 @@
2
2
 
3
3
  module Kuby
4
4
  class Definition
5
- extend T::Sig
5
+ # extend T::Sig
6
6
 
7
- sig { returns(String) }
7
+ # T::Sig::WithoutRuntime.sig { returns(String) }
8
8
  attr_reader :app_name
9
9
 
10
- sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
10
+ # T::Sig::WithoutRuntime.sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
11
11
  def initialize(app_name, &block)
12
12
  @app_name = app_name
13
- @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
13
+ # @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
14
14
  end
15
15
 
16
- sig {
17
- params(
18
- name: Symbol,
19
- block: T.nilable(T.proc.void)
20
- ).returns(Environment)
21
- }
16
+ # T::Sig::WithoutRuntime.sig {
17
+ # params(
18
+ # name: Symbol,
19
+ # block: T.nilable(T.proc.void)
20
+ # ).returns(Kuby::Environment)
21
+ # }
22
22
  def environment(name = Kuby.env, &block)
23
23
  name = name.to_s
24
24
 
@@ -28,10 +28,10 @@ module Kuby
28
28
  environments[name].instance_eval(&block)
29
29
  end
30
30
 
31
- T.must(environments[name])
31
+ environments[name]
32
32
  end
33
33
 
34
- sig { returns(T::Hash[Symbol, Environment]) }
34
+ # T::Sig::WithoutRuntime.sig { returns(T::Hash[Symbol, Kuby::Environment]) }
35
35
  def environments
36
36
  @environments ||= {}
37
37
  end
@@ -0,0 +1,20 @@
1
+ module Kuby
2
+ class Dependable
3
+ attr_reader :name, :version_or_callable
4
+
5
+ def initialize(name, version_or_callable)
6
+ @name = name
7
+ @version_or_callable = version_or_callable
8
+ end
9
+
10
+ def version
11
+ @version ||= Kuby::Utils::SemVer.parse_version(
12
+ if version_or_callable.respond_to?(:call)
13
+ version_or_callable.call
14
+ else
15
+ version_or_callable
16
+ end
17
+ )
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Kuby
2
+ class Dependency
3
+ attr_reader :name, :constraints
4
+
5
+ def initialize(name, *constraints)
6
+ @name = name
7
+ @constraints = Kuby::Utils::SemVer.parse_constraints(*constraints)
8
+ end
9
+
10
+ def satisfied_by?(dependable)
11
+ constraints.satisfied_by?(dependable.version)
12
+ end
13
+ end
14
+ end
@@ -3,42 +3,42 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class Alpine < Distro
6
- SHELL_EXE = T.let('/bin/sh'.freeze, String)
6
+ SHELL_EXE = '/bin/sh'.freeze
7
7
 
8
- DEFAULT_PACKAGES = T.let([
8
+ DEFAULT_PACKAGES = [
9
9
  [:ca_certificates, nil],
10
10
  [:nodejs, '12.14.1'],
11
11
  [:yarn, '1.21.1'],
12
12
  [:c_toolchain, nil],
13
13
  [:tzdata, nil],
14
14
  [:git, nil]
15
- ].freeze, T::Array[[Symbol, T.nilable(String)]])
15
+ ].freeze
16
16
 
17
- sig { returns(Layer) }
17
+ # T::Sig::WithoutRuntime.sig { returns(Layer) }
18
18
  attr_reader :phase
19
19
 
20
- sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
20
+ # T::Sig::WithoutRuntime.sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
21
21
  def install(packages, into:)
22
22
  dockerfile = into
23
23
  install_managed(packages, dockerfile)
24
24
  install_unmanaged(packages, dockerfile)
25
25
  end
26
26
 
27
- sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
27
+ # T::Sig::WithoutRuntime.sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
28
28
  def default_packages
29
29
  DEFAULT_PACKAGES
30
30
  end
31
31
 
32
- sig { override.returns(String) }
32
+ # T::Sig::WithoutRuntime.sig { override.returns(String) }
33
33
  def shell_exe
34
34
  SHELL_EXE
35
35
  end
36
36
 
37
37
  private
38
38
 
39
- sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
39
+ # T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
40
40
  def install_managed(packages, dockerfile)
41
- pkgs = T.cast(packages.select(&:managed?), T::Array[Distro::ManagedPackageImpl])
41
+ pkgs = packages.select(&:managed?)
42
42
 
43
43
  unless pkgs.empty?
44
44
  package_names = pkgs.map { |pkg| pkg.package_name_for(:alpine) }
@@ -48,7 +48,7 @@ module Kuby
48
48
  end
49
49
  end
50
50
 
51
- sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
51
+ # T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
52
52
  def install_unmanaged(packages, dockerfile)
53
53
  packages
54
54
  .reject(&:managed?)
@@ -4,18 +4,18 @@
4
4
  module Kuby
5
5
  module Docker
6
6
  class AppImage < ::Kuby::Docker::TimestampedImage
7
- extend T::Sig
7
+ # extend T::Sig
8
8
 
9
- sig {
10
- params(
11
- dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
12
- image_url: String,
13
- credentials: Credentials,
14
- registry_index_url: T.nilable(String),
15
- main_tag: T.nilable(String),
16
- alias_tags: T::Array[String]
17
- ).void
18
- }
9
+ # T::Sig::WithoutRuntime.sig {
10
+ # params(
11
+ # dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
12
+ # image_url: String,
13
+ # credentials: Credentials,
14
+ # registry_index_url: T.nilable(String),
15
+ # main_tag: T.nilable(String),
16
+ # alias_tags: T::Array[String]
17
+ # ).void
18
+ # }
19
19
  def initialize(dockerfile, image_url, credentials, registry_index_url = nil, main_tag = nil, alias_tags = [])
20
20
  super
21
21
  @identifier = "app"
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+
3
+ module Kuby
4
+ module Docker
5
+ class AppPhase < Layer
6
+ # extend T::Sig
7
+
8
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
9
+ def initialize(environment)
10
+ super
11
+
12
+ @env_vars = {}
13
+ end
14
+
15
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
16
+ def apply_to(dockerfile)
17
+ @env_vars.each_pair do |key, value|
18
+ dockerfile.env("#{key}='#{value}'")
19
+ end
20
+
21
+ absolute_app_root = Pathname(dockerfile.current_workdir)
22
+ .join(environment.docker.app_root_path)
23
+ .to_s
24
+
25
+ if dockerfile.current_workdir != absolute_app_root
26
+ dockerfile.workdir(absolute_app_root)
27
+ end
28
+ end
29
+
30
+ # T::Sig::WithoutRuntime.sig { params(key: String, value: String).void }
31
+ def env(key, value)
32
+ @env_vars[key] = value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,9 +3,9 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class AssetsPhase < Layer
6
- extend T::Sig
6
+ # extend T::Sig
7
7
 
8
- sig { override.params(dockerfile: Dockerfile).void }
8
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
9
9
  def apply_to(dockerfile)
10
10
  dockerfile.run(
11
11
  'bundle', 'exec', 'rake', 'assets:precompile'
@@ -5,101 +5,103 @@ require 'pathname'
5
5
  module Kuby
6
6
  module Docker
7
7
  class BundlerPhase < Layer
8
- extend T::Sig
8
+ # extend T::Sig
9
9
 
10
- DEFAULT_WITHOUT = T.let(
11
- ['development', 'test', 'deploy'].freeze, T::Array[String]
12
- )
10
+ DEFAULT_GEMFILE = 'Gemfile'.freeze
11
+ DEFAULT_WITHOUT =
12
+ ['development', 'test', 'deploy'].freeze
13
+
13
14
 
14
- sig { returns(T.nilable(String)) }
15
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
15
16
  attr_reader :version
16
17
 
17
- sig { params(version: String).void }
18
+ # T::Sig::WithoutRuntime.sig { params(version: String).returns(String) }
18
19
  attr_writer :version
19
20
 
20
- sig { returns(T.nilable(String)) }
21
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
21
22
  attr_reader :gemfile
22
23
 
23
- sig { params(gemfile: String).void }
24
+ # T::Sig::WithoutRuntime.sig { params(gemfile: String).returns(String) }
24
25
  attr_writer :gemfile
25
26
 
26
- sig { returns(T.nilable(T::Array[String])) }
27
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(T::Array[String])) }
27
28
  attr_reader :without
28
29
 
29
- sig { params(without: T::Array[String]).void }
30
+ # T::Sig::WithoutRuntime.sig { params(without: T::Array[String]).returns(T::Array[String]) }
30
31
  attr_writer :without
31
32
 
32
- sig { returns(T.nilable(String)) }
33
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
33
34
  attr_reader :executable
34
35
 
35
- sig { params(executable: String).void }
36
+ # T::Sig::WithoutRuntime.sig { params(executable: String).returns(String) }
36
37
  attr_writer :executable
37
38
 
38
- sig { params(environment: Environment).void }
39
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
39
40
  def initialize(environment)
40
41
  super
41
42
 
42
- @version = T.let(@version, T.nilable(String))
43
- @gemfile = T.let(@gemfile, T.nilable(String))
44
- @gemfiles = T.let([], T::Array[String])
45
- @without = T.let(@without, T.nilable(T::Array[String]))
46
- @executable = T.let(@executable, T.nilable(String))
43
+ # @version = T.let(@version, T.nilable(String))
44
+ # @gemfile = T.let(@gemfile, T.nilable(String))
45
+ @gemfiles = []
46
+ # @without = T.let(@without, T.nilable(T::Array[String]))
47
+ # @executable = T.let(@executable, T.nilable(String))
47
48
  end
48
49
 
49
- sig { override.params(dockerfile: Dockerfile).void }
50
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
50
51
  def apply_to(dockerfile)
51
- gf = gemfile || default_gemfile
52
+ gf = gemfile || DEFAULT_GEMFILE
52
53
  lf = "#{gf}.lock"
53
54
  v = version || default_version
54
55
  wo = without || DEFAULT_WITHOUT
55
56
 
56
- dockerfile.run('gem', 'install', 'bundler', '-v', v)
57
+ host_path = Pathname(environment.docker.app_root_path)
58
+ container_path = Pathname(dockerfile.current_workdir).join(environment.docker.app_root_path)
57
59
 
58
- # bundle install
59
- dockerfile.copy(gf, '.')
60
- dockerfile.copy(lf, '.')
60
+ dockerfile.run('gem', 'install', 'bundler', '-v', v)
61
61
 
62
+ dockerfile.copy(host_path.join(gf), container_path.join(gf))
63
+ dockerfile.copy(host_path.join(lf), container_path.join(lf))
62
64
  @gemfiles.each do |file|
63
- dockerfile.copy(file, file)
65
+ dockerfile.copy(host_path.join(file), container_path.join(file))
66
+ extra_lf = host_path.join("#{file}.lock")
67
+
68
+ if extra_lf.exist?
69
+ dockerfile.copy(extra_lf, container_path.join("#{file}.lock"))
70
+ end
64
71
  end
65
72
 
73
+ dockerfile.env("BUNDLE_GEMFILE=#{container_path.join(gf)}")
74
+
66
75
  unless wo.empty?
67
76
  dockerfile.env("BUNDLE_WITHOUT='#{wo.join(' ')}'")
68
77
  end
69
78
 
79
+ dockerfile.run(
80
+ executable || 'bundle', 'lock', '--lockfile', container_path.join(lf)
81
+ )
82
+
70
83
  dockerfile.run(
71
84
  executable || 'bundle', 'install',
72
85
  '--jobs', '$(nproc)',
73
- '--retry', '3',
74
- '--gemfile', gf
86
+ '--retry', '3'
75
87
  )
76
88
 
77
89
  # generate binstubs and add the bin directory to our path
78
90
  dockerfile.run(executable || 'bundle', 'binstubs', '--all')
79
- dockerfile.env("PATH=./bin:$PATH")
91
+ dockerfile.env("PATH=#{container_path.join('bin')}:$PATH")
80
92
  end
81
93
 
82
- sig { params(paths: String).void }
94
+ # T::Sig::WithoutRuntime.sig { params(paths: String).void }
83
95
  def gemfiles(*paths)
84
96
  @gemfiles.concat(paths)
85
97
  end
86
98
 
87
99
  private
88
100
 
89
- sig { returns(String) }
101
+ # T::Sig::WithoutRuntime.sig { returns(String) }
90
102
  def default_version
91
103
  Bundler::VERSION
92
104
  end
93
-
94
- sig { returns(String) }
95
- def default_gemfile
96
- Bundler
97
- .definition
98
- .gemfiles
99
- .first
100
- .relative_path_from(Pathname(Dir.getwd))
101
- .to_s
102
- end
103
105
  end
104
106
  end
105
107
  end
@@ -7,29 +7,29 @@ require 'shellwords'
7
7
  module Kuby
8
8
  module Docker
9
9
  class CLI < CLIBase
10
- extend T::Sig
10
+ # extend T::Sig
11
11
 
12
- sig { returns(String) }
12
+ # T::Sig::WithoutRuntime.sig { returns(String) }
13
13
  attr_reader :executable
14
14
 
15
- sig { params(executable: T.nilable(String)).void }
15
+ # T::Sig::WithoutRuntime.sig { params(executable: T.nilable(String)).void }
16
16
  def initialize(executable = nil)
17
- @executable = T.let(executable || `which docker`.strip, String)
17
+ @executable = executable || Kuby::Utils.which('docker')
18
18
  end
19
19
 
20
- sig { returns(T.nilable(String)) }
20
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
21
21
  def config_file
22
22
  if File.exist?(default_config_file)
23
23
  default_config_file
24
24
  end
25
25
  end
26
26
 
27
- sig { returns(String) }
27
+ # T::Sig::WithoutRuntime.sig { returns(String) }
28
28
  def default_config_file
29
29
  File.join(Dir.home, '.docker', 'config.json')
30
30
  end
31
31
 
32
- sig { params(url: String, username: String, password: String).void }
32
+ # T::Sig::WithoutRuntime.sig { params(url: String, username: String, password: String).void }
33
33
  def login(url:, username:, password:)
34
34
  cmd = [
35
35
  executable, 'login', url, '--username', username, '--password-stdin'
@@ -39,35 +39,43 @@ module Kuby
39
39
  stdin.puts(password)
40
40
  end
41
41
 
42
- unless T.must(last_status).success?
42
+ unless last_status.success?
43
43
  raise LoginError, 'build failed: docker command exited with '\
44
- "status code #{T.must(last_status).exitstatus}"
44
+ "status code #{last_status.exitstatus}"
45
45
  end
46
46
  end
47
47
 
48
- sig { returns(T::Array[String]) }
48
+ # T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
49
49
  def auths
50
50
  return [] unless config_file
51
51
 
52
- config = JSON.parse(File.read(T.must(config_file)))
52
+ config = JSON.parse(File.read(config_file))
53
53
  config.fetch('auths', {}).keys
54
54
  end
55
55
 
56
- sig {
57
- params(
58
- image: Image,
59
- build_args: T::Hash[T.any(Symbol, String), String],
60
- docker_args: T::Array[String],
61
- context: T.nilable(String)
62
- ).void
63
- }
64
- def build(image, build_args: {}, docker_args: [], context: nil)
56
+ # T::Sig::WithoutRuntime.sig {
57
+ # params(
58
+ # image: Image,
59
+ # build_args: T::Hash[T.any(Symbol, String), String],
60
+ # docker_args: T::Array[String],
61
+ # context: T.nilable(String),
62
+ # cache_from: T.nilable(String)
63
+ # ).void
64
+ # }
65
+ def build(image, build_args: {}, docker_args: [], context: nil, cache_from: nil)
65
66
  cmd = [
66
67
  executable, 'build',
67
68
  *image.tags.flat_map { |tag| ['-t', "#{image.image_url}:#{tag}"] },
68
69
  *build_args.flat_map do |arg, val|
69
70
  ['--build-arg', Shellwords.shellescape("#{arg}=#{val}")]
70
- end,
71
+ end
72
+ ]
73
+
74
+ if cache_from
75
+ cmd += ['--cache-from', cache_from]
76
+ end
77
+
78
+ cmd += [
71
79
  '-f-',
72
80
  *docker_args,
73
81
  context || '.'
@@ -77,21 +85,21 @@ module Kuby
77
85
  stdin.puts(image.dockerfile.to_s)
78
86
  end
79
87
 
80
- unless T.must(last_status).success?
88
+ unless last_status.success?
81
89
  raise BuildError, 'build failed: docker command exited with '\
82
- "status code #{T.must(last_status).exitstatus}"
90
+ "status code #{last_status.exitstatus}"
83
91
  end
84
92
  end
85
93
 
86
- sig {
87
- params(
88
- image_url: String,
89
- tag: String,
90
- env: T::Hash[T.any(Symbol, String), String],
91
- ports: T::Array[T.any(String, Integer)]
92
- )
93
- .void
94
- }
94
+ # T::Sig::WithoutRuntime.sig {
95
+ # params(
96
+ # image_url: String,
97
+ # tag: String,
98
+ # env: T::Hash[T.any(Symbol, String), String],
99
+ # ports: T::Array[T.any(String, Integer)]
100
+ # )
101
+ # .void
102
+ # }
95
103
  def run(image_url:, tag: 'latest', env: {}, ports: [])
96
104
  cmd = [
97
105
  executable, 'run',
@@ -105,13 +113,33 @@ module Kuby
105
113
  execc(cmd)
106
114
  end
107
115
 
108
- sig { params(image_url: String).returns(T::Array[T::Hash[Symbol, String]]) }
109
- def images(image_url)
116
+ # T::Sig::WithoutRuntime.sig { params(container: String, command: String, tty: T::Boolean).returns(String) }
117
+ def exec_capture(container:, command:, tty: true)
118
+ cmd = [executable, 'exec']
119
+ cmd << '-it' if tty
120
+ cmd += [container, command]
121
+
122
+ backticks(cmd)
123
+ end
124
+
125
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String, format: T.nilable(String)).returns(String) }
126
+ def inspect(image_url:, tag: 'latest', format: nil)
127
+ cmd = [executable, 'inspect']
128
+ cmd += ['--format', "'#{format}'"]
129
+ cmd << "#{image_url}:#{tag}"
130
+
131
+ backticks(cmd)
132
+ end
133
+
134
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, digests: T::Boolean).returns(T::Array[T::Hash[Symbol, String]]) }
135
+ def images(image_url, digests: true)
110
136
  cmd = [
111
137
  executable, 'images', image_url,
112
138
  '--format', '"{{json . }}"'
113
139
  ]
114
140
 
141
+ cmd << '--digests' if digests
142
+
115
143
  backticks(cmd).split("\n").map do |image_data|
116
144
  JSON.parse(image_data).each_with_object({}) do |(k, v), ret|
117
145
  ret[k.underscore.to_sym] = v
@@ -119,41 +147,41 @@ module Kuby
119
147
  end
120
148
  end
121
149
 
122
- sig { params(image_url: String, tag: String).void }
150
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
123
151
  def push(image_url, tag)
124
152
  systemm([
125
153
  executable, 'push', "#{image_url}:#{tag}"
126
154
  ])
127
155
 
128
- unless T.must(last_status).success?
156
+ unless last_status.success?
129
157
  raise PushError, 'push failed: docker command exited with '\
130
- "status code #{T.must(last_status).exitstatus}"
158
+ "status code #{last_status.exitstatus}"
131
159
  end
132
160
  end
133
161
 
134
- sig { params(image_url: String, tag: String).void }
162
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
135
163
  def pull(image_url, tag)
136
164
  systemm([
137
165
  executable, 'pull', "#{image_url}:#{tag}"
138
166
  ])
139
167
 
140
- unless T.must(last_status).success?
168
+ unless last_status.success?
141
169
  raise PullError, 'pull failed: docker command exited with '\
142
- "status code #{T.must(last_status).exitstatus}"
170
+ "status code #{last_status.exitstatus}"
143
171
  end
144
172
  end
145
173
 
146
- sig { returns(Symbol) }
174
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
147
175
  def status_key
148
176
  :kuby_docker_cli_last_status
149
177
  end
150
178
 
151
- sig { returns(Symbol) }
179
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
152
180
  def stdout_key
153
181
  :kuby_docker_stdout
154
182
  end
155
183
 
156
- sig { returns(Symbol) }
184
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
157
185
  def stderr_key
158
186
  :kuby_docker_stderr
159
187
  end
@@ -3,25 +3,25 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class CopyPhase < Layer
6
- extend T::Sig
6
+ # extend T::Sig
7
7
 
8
- DEFAULT_PATHS = T.let(['./'].freeze, T::Array[String])
8
+ DEFAULT_PATHS = ['./'].freeze
9
9
 
10
- sig { returns(T::Array[String]) }
10
+ # T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
11
11
  attr_reader :paths
12
12
 
13
- sig { params(environment: Environment).void }
13
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
14
14
  def initialize(environment)
15
15
  super
16
- @paths = T.let([], T::Array[String])
16
+ @paths = []
17
17
  end
18
18
 
19
- sig { params(path: String).void }
19
+ # T::Sig::WithoutRuntime.sig { params(path: String).void }
20
20
  def <<(path)
21
21
  paths << path
22
22
  end
23
23
 
24
- sig { params(dockerfile: Dockerfile).void }
24
+ # T::Sig::WithoutRuntime.sig { params(dockerfile: Dockerfile).void }
25
25
  def apply_to(dockerfile)
26
26
  to_copy = paths.empty? ? DEFAULT_PATHS : paths
27
27
  to_copy.each { |path| dockerfile.copy(path, '.') }
@@ -1,4 +1,5 @@
1
1
  # typed: strict
2
+
2
3
  require 'kube-dsl'
3
4
 
4
5
  module Kuby