Class: DockerfileMerge

Inherits:
Object
  • Object
show all
Defined in:
lib/dockerfilemerge.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw_s) ⇒ DockerfileMerge

Returns a new instance of DockerfileMerge.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/dockerfilemerge.rb', line 12

def initialize(raw_s)

  s, type = RXFHelper.read(raw_s)

  patterns = [
    [: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 :from

      lines << line
      lines << '' if r.length > 1        
      
    when :comment

      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

Instance Attribute Details

#to_sObject (readonly)

Returns the value of attribute to_s.



10
11
12
# File 'lib/dockerfilemerge.rb', line 10

def to_s
  @to_s
end