donce 0.0.4 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87e27e95378a5ad34a9ba6a7ef7c8578efb3d24990998beada04097c1a46d5c1
4
- data.tar.gz: 0ea31ae8977024be7abdbc164a3250a8eb907511ea24b5427b2eb3f8960b2912
3
+ metadata.gz: 77e8fc303600f62224be74352774a1d7d2a0e151cf4935316112874bf2b4c39f
4
+ data.tar.gz: 220d2d7b9fcdcd4702fb594daf2211a0268f54a7fc21231bbf8e4a670f75d796
5
5
  SHA512:
6
- metadata.gz: df41062bb8aea186f7bafc2df0070d7abbf1238d2eea5270f49a62e1901a495b0d50afca4659b5314ea0ea0117a299241b8757369a07b5e384cd8595abf956f2
7
- data.tar.gz: 2d6de2cde5d5df5dc3048bb7e9d68cc8b866ec76842f9ce7f9441a4b3b1f683a58e65428c558244c02ab2bcf1a6760606f1e63cea7a7c1a77f08778a18c59fd4
6
+ metadata.gz: 5e70dc715fb1b8166a6bf0805639b7f384e5f346438fdd8c030444d02a7fee8bcfb042ccd1bf71ef095ca201f1dbb4f586a30fe50a102686eb5b4dff6e6e2ee8
7
+ data.tar.gz: 2a4bf49df247f331a36dfaffb055a66f38e207dda78133c49d7db95e7178be4421253803d456e931cb40227802142c7f5d7363b11cb36345d85c662d79f00800
data/Gemfile CHANGED
@@ -28,7 +28,7 @@ gem 'minitest', '5.25.4', require: false
28
28
  gem 'minitest-reporters', '1.7.1', require: false
29
29
  gem 'minitest-retry', '0.2.5', require: false
30
30
  gem 'rake', '13.2.1', require: false
31
- gem 'rspec-rails', '7.1.0', require: false
31
+ gem 'rspec-rails', '7.1.1', require: false
32
32
  gem 'rubocop', '1.71.2', require: false
33
33
  gem 'rubocop-minitest', '0.36.0', require: false
34
34
  gem 'rubocop-performance', '1.23.1', require: false
data/Gemfile.lock CHANGED
@@ -134,7 +134,7 @@ GEM
134
134
  reline (0.6.0)
135
135
  io-console (~> 0.5)
136
136
  rexml (3.4.0)
137
- rspec-core (3.13.2)
137
+ rspec-core (3.13.3)
138
138
  rspec-support (~> 3.13.0)
139
139
  rspec-expectations (3.13.3)
140
140
  diff-lcs (>= 1.2.0, < 2.0)
@@ -142,7 +142,7 @@ GEM
142
142
  rspec-mocks (3.13.2)
143
143
  diff-lcs (>= 1.2.0, < 2.0)
144
144
  rspec-support (~> 3.13.0)
145
- rspec-rails (7.1.0)
145
+ rspec-rails (7.1.1)
146
146
  actionpack (>= 7.0)
147
147
  activesupport (>= 7.0)
148
148
  railties (>= 7.0)
@@ -213,7 +213,7 @@ DEPENDENCIES
213
213
  minitest-reporters (= 1.7.1)
214
214
  minitest-retry (= 0.2.5)
215
215
  rake (= 13.2.1)
216
- rspec-rails (= 7.1.0)
216
+ rspec-rails (= 7.1.1)
217
217
  rubocop (= 1.71.2)
218
218
  rubocop-minitest (= 0.36.0)
219
219
  rubocop-performance (= 1.23.1)
data/donce.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
27
  s.required_ruby_version = '>=3.0'
28
28
  s.name = 'donce'
29
- s.version = '0.0.4'
29
+ s.version = '0.1.0'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Builds and starts temporary Docker containers'
32
32
  s.description =
data/lib/donce.rb CHANGED
@@ -68,18 +68,21 @@ module Kernel
68
68
 
69
69
  # Build Docker image (or use existing one), run Docker container, and then clean up.
70
70
  #
71
- # @param [String] dockerfile The content of the +Dockerfile+
71
+ # @param [String] dockerfile The content of the +Dockerfile+ (if array is provided, it will be concatenated)
72
72
  # @param [String] home The directory with Dockerfile and all other necessary files
73
73
  # @param [String] image The name of Docker image, e.g. "ubuntu:24.04"
74
74
  # @param [Logger] log The logging destination, can be +$stdout+
75
75
  # @param [String|Array<String>] args List of extra arguments for the +docker+ command
76
76
  # @param [Hash<String,String>] env Environment variables going into the container
77
+ # @param [Hash<String,String>] volumes Local to container volumes mapping
78
+ # @param [Hash<String,String>] ports Local to container port mapping
79
+ # @param [Hash<String,String>] build_args Arguments for +docker build+ as +--build-arg+ may need
77
80
  # @param [Boolean] root Let user inside the container be "root"?
78
81
  # @param [String|Array<String>] command The command for the script inside the container
79
82
  # @param [Integer] timeout Maximum seconds to spend on each +docker+ call
80
83
  # @return [String] The stdout of the container
81
84
  def donce(dockerfile: nil, image: nil, home: nil, log: $stdout, args: '', env: {}, root: false, command: '',
82
- timeout: 10)
85
+ timeout: 10, volumes: {}, ports: {}, build_args: {})
83
86
  raise 'Either use "dockerfile" or "home"' if dockerfile && home
84
87
  raise 'Either use "dockerfile" or "image"' if dockerfile && image
85
88
  raise 'Either use "image" or "home"' if home && image
@@ -90,13 +93,20 @@ module Kernel
90
93
  image
91
94
  else
92
95
  i = "donce-#{SecureRandom.hex(6)}"
96
+ a = [
97
+ "--tag #{i}",
98
+ build_args.map { |k, v| "--build-arg #{Shellwords.escape("#{k}=#{v}")}" }.join(' ')
99
+ ].join(' ')
93
100
  if dockerfile
94
101
  Dir.mktmpdir do |tmp|
102
+ dockerfile = dockerfile.join("\n") if dockerfile.is_a?(Array)
95
103
  File.write(File.join(tmp, 'Dockerfile'), dockerfile)
96
- qbash("#{docker} build #{Shellwords.escape(tmp)} -t #{i}", log:)
104
+ qbash("#{docker} build #{a} #{Shellwords.escape(tmp)}", log:)
97
105
  end
106
+ elsif home
107
+ qbash("#{docker} build #{a} #{Shellwords.escape(home)}", log:)
98
108
  else
99
- qbash("#{docker} build #{Shellwords.escape(home)} -t #{i}", log:)
109
+ raise 'Either "dockerfile" or "home" must be provided'
100
110
  end
101
111
  i
102
112
  end
@@ -107,15 +117,17 @@ module Kernel
107
117
  begin
108
118
  cmd = [
109
119
  docker, 'run',
110
- block_given? ? '-d' : '',
120
+ block_given? ? '--detach' : nil,
111
121
  '--name', Shellwords.escape(container),
112
- OS.linux? ? '' : "--add-host #{donce_host}:host-gateway",
122
+ OS.linux? ? nil : "--add-host #{donce_host}:host-gateway",
113
123
  args,
114
- env.map { |k, v| "-e #{Shellwords.escape("#{k}=#{v}")}" }.join(' '),
115
- root ? '' : "--user=#{Shellwords.escape("#{Process.uid}:#{Process.gid}")}",
124
+ env.map { |k, v| "--env #{Shellwords.escape("#{k}=#{v}")}" }.join(' '),
125
+ ports.map { |k, v| "--publish #{Shellwords.escape("#{k}:#{v}")}" }.join(' '),
126
+ volumes.map { |k, v| "--volume #{Shellwords.escape("#{k}:#{v}")}" }.join(' '),
127
+ root ? nil : "--user=#{Shellwords.escape("#{Process.uid}:#{Process.gid}")}",
116
128
  Shellwords.escape(img),
117
129
  command
118
- ].join(' ')
130
+ ].compact.join(' ')
119
131
  stdout, code =
120
132
  Timeout.timeout(timeout) do
121
133
  qbash(
@@ -140,7 +152,7 @@ module Kernel
140
152
  log:
141
153
  )
142
154
  stdout = logs if block_given?
143
- qbash("#{docker} rm -f #{Shellwords.escape(container)}", log:)
155
+ qbash("#{docker} rm --force #{Shellwords.escape(container)}", log:)
144
156
  end
145
157
  stdout
146
158
  ensure
data/test/test_donce.rb CHANGED
@@ -34,6 +34,20 @@ class TestDonce < Minitest::Test
34
34
  assert_equal("hello\n", stdout)
35
35
  end
36
36
 
37
+ def test_prints_build_args
38
+ stdout = donce(
39
+ dockerfile: [
40
+ 'FROM ubuntu',
41
+ 'ARG FOO=what?',
42
+ 'RUN echo $FOO > /tmp/foo',
43
+ 'CMD cat /tmp/foo'
44
+ ],
45
+ build_args: { 'FOO' => 'hello' },
46
+ log: Loog::NULL
47
+ )
48
+ assert_equal("hello\n", stdout)
49
+ end
50
+
37
51
  def test_runs_existing_image
38
52
  stdout = donce(image: 'ubuntu:24.04', command: 'echo hello', log: Loog::NULL)
39
53
  assert_equal("hello\n", stdout)
@@ -47,6 +61,24 @@ class TestDonce < Minitest::Test
47
61
  end
48
62
  end
49
63
 
64
+ def test_copies_resources
65
+ content = 'hello!'
66
+ Dir.mktmpdir do |home|
67
+ File.write(File.join(home, 'test.txt'), content)
68
+ File.write(
69
+ File.join(home, 'Dockerfile'),
70
+ [
71
+ 'FROM ubuntu',
72
+ 'WORKDIR /foo',
73
+ 'COPY test.txt .',
74
+ 'CMD cat test.txt'
75
+ ].join("\n")
76
+ )
77
+ stdout = donce(home:, log: Loog::NULL)
78
+ assert_equal(content, stdout)
79
+ end
80
+ end
81
+
50
82
  def test_runs_daemon
51
83
  seen = false
52
84
  donce(dockerfile: "FROM ubuntu\nCMD while true; do sleep 1; echo sleeping; done", log: Loog::NULL) do |id|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: donce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-06 00:00:00.000000000 Z
11
+ date: 2025-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace