class Dockerfile::Merge
Attributes
to_s[R]
Public Class Methods
new(raw_s)
click to toggle source
# File lib/dockerfilemerge.rb, line 14 def initialize(raw_s) s, type = RXFHelper.read(raw_s) patterns = [ [:root, /^\s*ADD\s+(?<add>.*)/, :add], [:root, /^\s*COPY\s+(?<copy>.*)/, :copy], [:root, /FROM\s+(?<from>.*)/, :from], [:root, /INCLUDE\s*(?<path>.*)?/, :include], [:include, /(?<path>.*)/, :dockerfile], [:root, /MAINTAINER (?<name>.*)/, :maintainer], [:root, /RUN (?<command>.*)/, :run], [:root, /-\/[^\/]+\/(?:\[[^\]]+\])?/, :del], [:all, /#/, :comment] ] s.sub!(/\A# Dockermergefile/,'# Dockerfile') a = LineParser.new(patterns, ignore_blank_lines: false).parse s maintainer = a.grep /MAINTAINER/ if maintainer.empty? then from = a.assoc :include a.insert(a.index(from) + 1, [:maintainer, {},['MAINTAINER unknown']]) end lines = [] if type == :url then lines << '# Generated ' + Time.now.strftime("%a %d-%b-%Y %-I:%M%P") lines << '# source: ' + raw_s end a.each do |label, h, r, c| # h=hash, r=remaining, c=children line = r.first case label when :add lines << line lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1 when :comment lines << line lines << '' if r.length > 1 when :copy lines << line lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1 when :from lines << line lines << '' if r.length > 1 when :include h[:path].length > 0 ? merge_file(lines, h[:path]) : c.each {|source| merge_file lines, source[1][:path] } lines << '' if r.length > 1 when :maintainer maintainers = lines.grep(/MAINTAINER/) if maintainers.length > 0 then while maintainers.length > 1 do i = lines.rindex maintainers.pop lines.delete_at i maintainers = lines.grep(/MAINTAINER/) end i = lines.index maintainers[0] lines[i] = line unless line[/MAINTAINER unknown/] elsif maintainers.empty? from = lines.grep /^ *FROM\b/ i = lines.index from[0] lines.insert(i+1, line) unless line[/MAINTAINER unknown/] end when :run lines << line lines << ' ' + r[1..-1].join("\n ").rstrip if r.length > 1 when :del exp, filter = line.match(/-\/([^\/]+)\/(\[[^\]]+\])?/).captures name = if filter then case filter[1..-2] when'0..-2' :singlify_last when '1..-1' :singlify_first else puts 'unrecognised selector' end else :delete_all end method(name).call(lines, exp) if name.is_a? Symbol end end singlify_first lines, /^\s*FROM / singlify_last lines, /^\s*CMD / s = lines.join("\n") rm_sources = /rm -rf \/var\/lib\/apt\/lists\/\*/ rm_sources_count = s.scan(rm_sources).length if rm_sources_count > 1 then (rm_sources_count - 1).times { remove_command(rm_sources,s) } end @to_s = s end
Private Instance Methods
delete_all(lines, regex)
click to toggle source
# File lib/dockerfilemerge.rb, line 153 def delete_all(lines, regex) lines.reject! {|x| x[regex]} end
merge_file(lines, path)
click to toggle source
# File lib/dockerfilemerge.rb, line 157 def merge_file(lines, path) raw_buffer, type = RXFHelper.read(path) buffer = raw_buffer[/^\bINCLUDE\b/] ? \ DockerfileMerge.new(raw_buffer).to_s : raw_buffer rows = buffer.lines.map(&:chomp) lines << "\n\n# copied from " + path if type == :url rows.grep(/^# Pull /).each {|x| rows.delete x} lines.concat rows end
remove_command(regex, s)
click to toggle source
# File lib/dockerfilemerge.rb, line 170 def remove_command(regex, s) s.sub!(/(?:\\?\s*&&\s+)#{regex}\s*$|(?:RUN\s+|\s*&&\s+||&&\s*\\\s*)?#{regex}(?:\s+\\)? */,'') end
singlify_first(lines, raw_regex)
click to toggle source
removes any matching lines after the 1st matching line
# File lib/dockerfilemerge.rb, line 176 def singlify_first(lines, raw_regex) regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex) i = 0 lines.reject! {|x| found = x[regex]; i += 1 if found; i > 1 and found } end
singlify_last(lines, raw_regex)
click to toggle source
removes any matching lines before the last matching line
# File lib/dockerfilemerge.rb, line 185 def singlify_last(lines, raw_regex) regex = raw_regex.is_a?(Regexp) ? raw_regex : Regexp.new(raw_regex) lines.grep(regex)[0..-2].each {|x| lines.delete x} end