dockerfilemerge 0.4.6 → 0.5.0

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
- SHA1:
3
- metadata.gz: 63c76356146aaf73dba1e0c93aca46ee2560c001
4
- data.tar.gz: 651507190dc257065f1709d46d8df7a839091195
2
+ SHA256:
3
+ metadata.gz: ba02da0dcfd5851c24454cc8ac42dba746fb21a26d7c50d034df9b8f71aec990
4
+ data.tar.gz: 6c1c0a06b24f33be70c6ab21a89f1b1a335080f063419b24f29349e9b2e4f5f6
5
5
  SHA512:
6
- metadata.gz: 32f4f7a3cc4c18d08a092c49b41c889535dcd6fad6008c9a250fc999e132b58ff5153aa1d0e6708d064b0a56857212686cce3dd53d7ce878ac9e8f01c0d22e3e
7
- data.tar.gz: c0f419523dd3829bc00e7ee253c7501cef65f192b1f6768ea72459bbc5dfe7abbbbb7bb99e4fe568af23d59e58eda9f5e182d50e5287de9b537e081dc4ee4565
6
+ metadata.gz: 7e44b601db031e44d620a160abc8dbfeb847da73e9af61c5cfd977cc2eba780b1eb3694f31a03c8ee47c562ff6f8959e5d8e474be377faf0defd1d1a65d53eb6
7
+ data.tar.gz: 2529519b5920e59cb9631738b762554855f1611a958932766f8b5438f97fa16256b249f9fd49a26c473881a3018a0c9b30bb46bbee4a88be5d794d6549db226e
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -5,184 +5,231 @@
5
5
  require 'lineparser'
6
6
  require 'rxfhelper'
7
7
 
8
- class DockerfileMerge
8
+ module Dockerfile
9
+
10
+ class Merge
9
11
 
10
- attr_reader :to_s
12
+ attr_reader :to_s
11
13
 
12
- def initialize(raw_s)
14
+ def initialize(raw_s)
13
15
 
14
- s, type = RXFHelper.read(raw_s)
16
+ s, type = RXFHelper.read(raw_s)
15
17
 
16
- patterns = [
17
- [:root, /^\s*ADD\s+(?<add>.*)/, :add],
18
- [:root, /^\s*COPY\s+(?<copy>.*)/, :copy],
19
- [:root, /FROM\s+(?<from>.*)/, :from],
20
- [:root, /INCLUDE\s*(?<path>.*)?/, :include],
21
- [:include, /(?<path>.*)/, :dockerfile],
22
- [:root, /MAINTAINER (?<name>.*)/, :maintainer],
23
- [:root, /RUN (?<command>.*)/, :run],
24
- [:root, /-\/[^\/]+\/(?:\[[^\]]+\])?/, :del],
25
- [:all, /#/, :comment]
26
- ]
18
+ patterns = [
19
+ [:root, /^\s*ADD\s+(?<add>.*)/, :add],
20
+ [:root, /^\s*COPY\s+(?<copy>.*)/, :copy],
21
+ [:root, /FROM\s+(?<from>.*)/, :from],
22
+ [:root, /INCLUDE\s*(?<path>.*)?/, :include],
23
+ [:include, /(?<path>.*)/, :dockerfile],
24
+ [:root, /MAINTAINER (?<name>.*)/, :maintainer],
25
+ [:root, /RUN (?<command>.*)/, :run],
26
+ [:root, /-\/[^\/]+\/(?:\[[^\]]+\])?/, :del],
27
+ [:all, /#/, :comment]
28
+ ]
27
29
 
28
- s.sub!(/\A# Dockermergefile/,'# Dockerfile')
29
- a = LineParser.new(patterns, ignore_blank_lines: false).parse s
30
- maintainer = a.grep /MAINTAINER/
31
-
32
- if maintainer.empty? then
30
+ s.sub!(/\A# Dockermergefile/,'# Dockerfile')
31
+ a = LineParser.new(patterns, ignore_blank_lines: false).parse s
32
+ maintainer = a.grep /MAINTAINER/
33
+
34
+ if maintainer.empty? then
33
35
 
34
- from = a.assoc :include
35
- a.insert(a.index(from) + 1, [:maintainer, {},['MAINTAINER unknown']])
36
- end
36
+ from = a.assoc :include
37
+ a.insert(a.index(from) + 1, [:maintainer, {},['MAINTAINER unknown']])
38
+ end
37
39
 
38
- lines = []
39
-
40
- if type == :url then
41
- lines << '# Generated ' + Time.now.strftime("%a %d-%b-%Y %-I:%M%P")
42
- lines << '# source: ' + raw_s
43
- end
40
+ lines = []
41
+
42
+ if type == :url then
43
+ lines << '# Generated ' + Time.now.strftime("%a %d-%b-%Y %-I:%M%P")
44
+ lines << '# source: ' + raw_s
45
+ end
44
46
 
45
- a.each do |label, h, r, c| # h=hash, r=remaining, c=children
46
-
47
- line = r.first
48
-
49
- case label
47
+ a.each do |label, h, r, c| # h=hash, r=remaining, c=children
50
48
 
49
+ line = r.first
51
50
 
52
- when :add
51
+ case label
52
+
53
+
54
+ when :add
53
55
 
54
- lines << line
55
- lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
56
-
57
- when :comment
56
+ lines << line
57
+ lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
58
+
59
+ when :comment
58
60
 
59
- lines << line
60
- lines << '' if r.length > 1
61
-
62
-
63
- when :copy
61
+ lines << line
62
+ lines << '' if r.length > 1
63
+
64
+
65
+ when :copy
64
66
 
65
- lines << line
66
- lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
67
-
68
- when :from
67
+ lines << line
68
+ lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
69
+
70
+ when :from
69
71
 
70
- lines << line
71
- lines << '' if r.length > 1
72
-
72
+ lines << line
73
+ lines << '' if r.length > 1
74
+
73
75
 
74
- when :include
76
+ when :include
75
77
 
76
- h[:path].length > 0 ? merge_file(lines, h[:path]) :
77
- c.each {|source| merge_file lines, source[1][:path] }
78
- lines << '' if r.length > 1
78
+ h[:path].length > 0 ? merge_file(lines, h[:path]) :
79
+ c.each {|source| merge_file lines, source[1][:path] }
80
+ lines << '' if r.length > 1
79
81
 
80
- when :maintainer
82
+ when :maintainer
81
83
 
82
- maintainers = lines.grep(/MAINTAINER/)
84
+ maintainers = lines.grep(/MAINTAINER/)
83
85
 
84
- if maintainers.length > 0 then
85
-
86
- while maintainers.length > 1 do
87
- i = lines.rindex maintainers.pop
88
- lines.delete_at i
89
- maintainers = lines.grep(/MAINTAINER/)
90
- end
86
+ if maintainers.length > 0 then
87
+
88
+ while maintainers.length > 1 do
89
+ i = lines.rindex maintainers.pop
90
+ lines.delete_at i
91
+ maintainers = lines.grep(/MAINTAINER/)
92
+ end
91
93
 
92
- i = lines.index maintainers[0]
94
+ i = lines.index maintainers[0]
93
95
 
94
- lines[i] = line unless line[/MAINTAINER unknown/]
95
- elsif maintainers.empty?
96
+ lines[i] = line unless line[/MAINTAINER unknown/]
97
+ elsif maintainers.empty?
96
98
 
97
- from = lines.grep /^ *FROM\b/
98
- i = lines.index from[0]
99
- lines.insert(i+1, line) unless line[/MAINTAINER unknown/]
99
+ from = lines.grep /^ *FROM\b/
100
+ i = lines.index from[0]
101
+ lines.insert(i+1, line) unless line[/MAINTAINER unknown/]
100
102
 
101
- end
102
-
103
+ end
104
+
103
105
 
104
-
105
- when :run
106
+
107
+ when :run
106
108
 
107
- lines << line
108
- lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
109
-
110
-
111
- when :del
109
+ lines << line
110
+ lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1
111
+
112
+
113
+ when :del
112
114
 
113
- exp, filter = line.match(/-\/([^\/]+)\/(\[[^\]]+\])?/).captures
115
+ exp, filter = line.match(/-\/([^\/]+)\/(\[[^\]]+\])?/).captures
114
116
 
115
- name = if filter then
117
+ name = if filter then
116
118
 
117
- case filter[1..-2]
118
- when'0..-2'
119
- :singlify_last
120
- when '1..-1'
121
- :singlify_first
119
+ case filter[1..-2]
120
+ when'0..-2'
121
+ :singlify_last
122
+ when '1..-1'
123
+ :singlify_first
124
+ else
125
+ puts 'unrecognised selector'
126
+ end
122
127
  else
123
- puts 'unrecognised selector'
124
- end
125
- else
126
- :delete_all
127
- end
128
-
129
- method(name).call(lines, exp) if name.is_a? Symbol
128
+ :delete_all
129
+ end
130
+
131
+ method(name).call(lines, exp) if name.is_a? Symbol
132
+
133
+ end
130
134
 
131
- end
135
+ end
136
+
137
+ singlify_first lines, /^\s*FROM /
138
+ singlify_last lines, /^\s*CMD /
139
+ s = lines.join("\n")
140
+
141
+ rm_sources = /rm -rf \/var\/lib\/apt\/lists\/\*/
142
+ rm_sources_count = s.scan(rm_sources).length
132
143
 
144
+ if rm_sources_count > 1 then
145
+ (rm_sources_count - 1).times { remove_command(rm_sources,s) }
146
+ end
147
+
148
+ @to_s = s
133
149
  end
134
150
 
135
- singlify_first lines, /^\s*FROM /
136
- singlify_last lines, /^\s*CMD /
137
- s = lines.join("\n")
151
+ private
152
+
153
+ def delete_all(lines, regex)
154
+ lines.reject! {|x| x[regex]}
155
+ end
156
+
157
+ def merge_file(lines, path)
138
158
 
139
- rm_sources = /rm -rf \/var\/lib\/apt\/lists\/\*/
140
- rm_sources_count = s.scan(rm_sources).length
159
+ raw_buffer, type = RXFHelper.read(path)
160
+ buffer = raw_buffer[/^\bINCLUDE\b/] ? \
161
+ DockerfileMerge.new(raw_buffer).to_s : raw_buffer
162
+
163
+ rows = buffer.lines.map(&:chomp)
164
+ lines << "\n\n# copied from " + path if type == :url
165
+ rows.grep(/^# Pull /).each {|x| rows.delete x}
166
+
167
+ lines.concat rows
168
+ end
141
169
 
142
- if rm_sources_count > 1 then
143
- (rm_sources_count - 1).times { remove_command(rm_sources,s) }
170
+ def remove_command(regex, s)
171
+ s.sub!(/(?:\\?\s*&&\s+)#{regex}\s*$|(?:RUN\s+|\s*&&\s+||&&\s*\\\s*)?#{regex}(?:\s+\\)? */,'')
144
172
  end
145
173
 
146
- @to_s = s
147
- end
148
-
149
- private
150
-
151
- def delete_all(lines, regex)
152
- lines.reject! {|x| x[regex]}
153
- end
174
+ # removes any matching lines after the 1st matching line
175
+ #
176
+ def singlify_first(lines, raw_regex)
177
+
178
+ regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex)
179
+ i = 0
180
+ lines.reject! {|x| found = x[regex]; i += 1 if found; i > 1 and found }
181
+ end
154
182
 
155
- def merge_file(lines, path)
183
+ # removes any matching lines before the last matching line
184
+ #
185
+ def singlify_last(lines, raw_regex)
186
+
187
+ regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex)
188
+ lines.grep(regex)[0..-2].each {|x| lines.delete x}
189
+ end
190
+ end
156
191
 
157
- raw_buffer, type = RXFHelper.read(path)
158
- buffer = raw_buffer[/^\bINCLUDE\b/] ? \
159
- DockerfileMerge.new(raw_buffer).to_s : raw_buffer
192
+ class Split
160
193
 
161
- rows = buffer.lines.map(&:chomp)
162
- lines << "\n\n# copied from " + path if type == :url
163
- rows.grep(/^# Pull /).each {|x| rows.delete x}
164
-
165
- lines.concat rows
166
- end
167
-
168
- def remove_command(regex, s)
169
- s.sub!(/(?:\\?\s*&&\s+)#{regex}\s*$|(?:RUN\s+|\s*&&\s+||&&\s*\\\s*)?#{regex}(?:\s+\\)? */,'')
170
- end
171
-
172
- # removes any matching lines after the 1st matching line
173
- #
174
- def singlify_first(lines, raw_regex)
194
+ def initialize(xmlfile='dockerfiles.xml', repository: 'myrepo',
195
+ filepath: '.' , base_image: nil)
196
+
197
+ @repository, @filepath, @xmlfile = repository, filepath, xmlfile
198
+ @base_image = base_image
199
+
200
+ end
175
201
 
176
- regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex)
177
- i = 0
178
- lines.reject! {|x| found = x[regex]; i += 1 if found; i > 1 and found }
202
+ def make()
203
+
204
+ s = File.read(@xmlfile)
205
+ doc = Rexle.new(s)
206
+
207
+ a = doc.root.xpath('//dockerfile')
208
+ a.each.with_index do |entry, i|
209
+
210
+ filename = entry.attributes[:id]
211
+ path2 = File.join(@filepath, filename)
212
+ FileUtils.mkdir path2
213
+ File.write File.join(path2, 'Dockerfile'), entry.texts.join.strip\
214
+ .sub(/<base_image>/, @base_image)
215
+
216
+ s = "sudo docker build -t %s/%s ." % [@repository, filename]
217
+ File.write build_path=File.join(path2, 'build.sh'), s
218
+ FileUtils.chmod_R 0755, build_path
219
+
220
+ if i == 0 then
221
+
222
+ builds = "sudo build.sh && " + a[1..-1].map \
223
+ {|x| "cd ../%s && sudo build.sh" % x.attributes[:id] }.join(" && ")
224
+
225
+ File.write buildall_path=File.join(path2, 'buildall.sh'), builds
226
+ FileUtils.chmod_R 0755, buildall_path
227
+ end
228
+
229
+ end
230
+
231
+
232
+ end
179
233
  end
180
-
181
- # removes any matching lines before the last matching line
182
- #
183
- def singlify_last(lines, raw_regex)
184
-
185
- regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex)
186
- lines.grep(regex)[0..-2].each {|x| lines.delete x}
187
- end
188
- end
234
+
235
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockerfilemerge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -10,28 +10,32 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDljCCAn6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBIMRIwEAYDVQQDDAlnZW1t
14
- YXN0ZXIxHjAcBgoJkiaJk/IsZAEZFg5qYW1lc3JvYmVydHNvbjESMBAGCgmSJomT
15
- 8ixkARkWAmV1MB4XDTE1MDcwOTIyMjYxOVoXDTE2MDcwODIyMjYxOVowSDESMBAG
16
- A1UEAwwJZ2VtbWFzdGVyMR4wHAYKCZImiZPyLGQBGRYOamFtZXNyb2JlcnRzb24x
17
- EjAQBgoJkiaJk/IsZAEZFgJldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
18
- ggEBANN2xruCRBJcjqpnwZhgNr9xh5r+fEnHRRN9cVT7gSjF1QKUptpVILDXBjmo
19
- VRC2WyhB2ct0RiKaBMjtvh2k6sDkjkKzSu+2nsFrULhF7CmQ6KGZQ+xGmWK0rDnJ
20
- 7RgxYyE16APlhiFboYKg4DuIYbvHUvYkVJJc4d0cpm33QDLYV/qzM8tikHv1b3Z5
21
- 1x0w9YaCYY0qcwPkyT5iBNIOYETGu3QhO1qxSnMfchqPT3qSHEMURCqMd+YqUIqA
22
- reKHiU4/vtnnfblJoUkLHu5ncrTMzFOSMIx6sz9IkOoxUSIn5iQJ+BsJmL2ro83B
23
- t6aC1T35QveE9Cw8ollOk+/wwgECAwEAAaOBijCBhzAJBgNVHRMEAjAAMAsGA1Ud
24
- DwQEAwIEsDAdBgNVHQ4EFgQUUTTdbNjncxfVI4lCFCMDsGhs8WswJgYDVR0RBB8w
25
- HYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1h
26
- c3RlckBqYW1lc3JvYmVydHNvbi5ldTANBgkqhkiG9w0BAQUFAAOCAQEAfKIf6WI6
27
- wRrUjXB8O0M+NPxyn6xIFlFNwEr6hW6baJ03Qg6Gx61oRMhYpncK11bVAelmrd+t
28
- zR2hNqO0JNPxj8nreNO7bCQhv/jZBddarI01JxLAOqYqkdL/SNmXAkbyinQeHi/G
29
- CqIpCHhDwm1OyWM5LMXL/keJyYhV6zWsKss77mgs2eI7ngJIRumY61D0omp1mkkO
30
- plFRlsPmYWHR38dUWIcgORaoBvaxdTP4cJqq/+AElHvbeAJG/rLBGd9jF6tG8YZk
31
- WHpJ21HYl4KWG8TISerrdwpQAZ5dhV2Yy/4q0MWSnDcMRSYdRAixOcdYW+U+R8cz
32
- pf2JrQZNdYZXIg==
13
+ MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
14
+ YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMTkwNDA2MjEwMjM3WhcN
15
+ MjAwNDA1MjEwMjM3WjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
+ cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCaooNV
17
+ fX7aN+ifLKHmeFeuIJ+nd/sVFa2jGcyKtJWaBYu+aaVm75siS6paZEdAo7zw3NKt
18
+ CmQwK9nS7TCrbNa0VY07G0RwTM5JJPN6MIBVhZiO+sDG7i19ylqoBzLRjH8Xk62e
19
+ s+9gfbXgUj2STnoHpyjICyxWeRSdzNL+ZOtRFMJIPqqErGHVtS4IKbWN8uCL1mk1
20
+ piPC14lGHCAsP7fsXffneE93ibNvUFdv4tYw7SrMOIUFiqaKoVwP7tzktwGp7ofN
21
+ l6xm0/Gkd/ZM4Zt11qbSryUL2TU0TdpsOpmpxF90pQRziTX7ketBTvHX7LFm9tJj
22
+ /CQxcjTM33AvowEmX/DCFNoMXpeGjcdMeo1DC+4d+R1OzNs5pLU4957CJCkSpRb0
23
+ pUL0RziaJgLeRuZ0Irgd1nNGOenhdMe//6peaUBULsw352MdFQpnVssjUnxbYIjH
24
+ /EvzQBNWgu+eqcRIn//U/BRKzNvuEGF70sxIjIHxjOY1QNIMclZ3thS8aHECAwEA
25
+ AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUWunxNo4/
26
+ S4gA294O8BGCrhYZjxAwJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
27
+ c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
28
+ BgkqhkiG9w0BAQsFAAOCAYEAjI1vZ69Uf8vEOjRRhHKTWTQDjnnOONl6J27qelmw
29
+ qGHlphuZ6zPMyAlPe5rpk67A8/+tliTs1SQ+V17O0TZqLNDQKKNTXlgjt7INe360
30
+ V0IsdKnuI8p+gYikGm5PrrkARp0eNQfieZhSW3NTbhR5uVKkqpBzYKZtOgEeAVYT
31
+ XpuifxUTozSUr4wuwMEBnf795L9+eogB8a+at6pVhTGEfgomgGNv+h5W2RX4aRai
32
+ bjddYdB0MU6KGn2J6Z7w8RzqAqw5c59I+5O/A68fSGh2jRgJPxDW0qzrBj9djbL6
33
+ qv+dgXzEJc6iQIN7IdJyKs2kRroolKSVru/ACB6ppsUxfASud20OyrJRudMJzRQH
34
+ Rwfa6N2cxBitxIs+cca9gMgAMZtQvbWg4LgwqOjio8cKbW6HKc63PXEkIP7/sC5i
35
+ zfrmvNAOB2nUhx8eE6ES7atIe0Fq1AFX8hX3guVTzqPW9J71heSwNzc7oxQW8u93
36
+ nByUcsaYHMsVhsqOgbKoqjA5
33
37
  -----END CERTIFICATE-----
34
- date: 2015-08-05 00:00:00.000000000 Z
38
+ date: 2019-04-06 00:00:00.000000000 Z
35
39
  dependencies:
36
40
  - !ruby/object:Gem::Dependency
37
41
  name: lineparser
@@ -42,7 +46,7 @@ dependencies:
42
46
  version: '0.1'
43
47
  - - ">="
44
48
  - !ruby/object:Gem::Version
45
- version: 0.1.15
49
+ version: 0.1.19
46
50
  type: :runtime
47
51
  prerelease: false
48
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -52,29 +56,29 @@ dependencies:
52
56
  version: '0.1'
53
57
  - - ">="
54
58
  - !ruby/object:Gem::Version
55
- version: 0.1.15
59
+ version: 0.1.19
56
60
  - !ruby/object:Gem::Dependency
57
61
  name: rxfhelper
58
62
  requirement: !ruby/object:Gem::Requirement
59
63
  requirements:
60
64
  - - "~>"
61
65
  - !ruby/object:Gem::Version
62
- version: '0.2'
66
+ version: '0.9'
63
67
  - - ">="
64
68
  - !ruby/object:Gem::Version
65
- version: 0.2.3
69
+ version: 0.9.4
66
70
  type: :runtime
67
71
  prerelease: false
68
72
  version_requirements: !ruby/object:Gem::Requirement
69
73
  requirements:
70
74
  - - "~>"
71
75
  - !ruby/object:Gem::Version
72
- version: '0.2'
76
+ version: '0.9'
73
77
  - - ">="
74
78
  - !ruby/object:Gem::Version
75
- version: 0.2.3
79
+ version: 0.9.4
76
80
  description:
77
- email: james@r0bertson.co.uk
81
+ email: james@jamesrobertson.eu
78
82
  executables: []
79
83
  extensions: []
80
84
  extra_rdoc_files: []
@@ -99,9 +103,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
103
  - !ruby/object:Gem::Version
100
104
  version: '0'
101
105
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.4.8
106
+ rubygems_version: 3.0.1
104
107
  signing_key:
105
108
  specification_version: 4
106
- summary: Merge 2 or more Dockerfiles into 1 Dockerfile
109
+ summary: Merge 2 or more Dockerfiles into 1 Dockerfile, or split Dockerfiles apart
110
+ from an XML file
107
111
  test_files: []
metadata.gz.sig CHANGED
Binary file