Module: DansGuardian::Updater

Defined in:
lib/dansguardian/updater.rb

Class Method Summary collapse

Class Method Details

.update(io_or_file, data) ⇒ Object

Like update! but also accept IO objects and yields updated lines instead of actually writing to a file.



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
# File 'lib/dansguardian/updater.rb', line 22

def self.update(io_or_file, data)
  if io_or_file.is_a? IO
    io = io_or_file
  else
    io = File.open io_or_file
  end

  already_written = [] 
  io.each_line do |line|
    line.strip!
    case line
    # even replace commented lines
    when /^(#\s*)?([^=\s#]+)\s*=\s*([^=\s#']*)/  
      key = $2
      value = $3
    when /^(#\s*)?[\s#]*([^=\s#]+)\s*=\s*'(.*)'/ 
      key = $2
      value = $3.gsub(/\\'/, "'")
    else
      yield line # not a key/val line: leave untouched
      next
    end

    # At this point, it is actually a key/value line

    next if 
        already_written.include?(key)         or 
        already_written.include?(key.to_sym)

    new_value = ( data[key] || data[key.to_sym] )
    if new_value
      if new_value.respond_to? :each # multiple values
        new_value.each do |val|
          yield "#{key} = #{val}"
        end
      else
        if new_value == :remove!
          yield "# #{line}" 
        else
          yield "#{key} = #{new_value}"
        end
      end
      already_written << key
      # next # "optimized out"
    else # not a key/val pair to edit: leave untouched
      yield line
      # next # "optimized out"
    end
  end

  to_be_written = 
      data.keys.map{|k| k.to_sym} - already_written.map{|k| k.to_sym}
  to_be_written.select!{|k| data[k.to_s] || data[k.to_sym]} # reject nil values
  to_be_written.reject! do |k|
    (data[k.to_s] || data[k.to_sym]) == :remove!
  end
  if to_be_written.length > 0
    to_be_written.each do |k|
      v = data[k] || data[k.to_s]
      if v.respond_to? :each
        v.each do |val|
          yield "#{k} = #{val}"  
        end
      else
        yield "#{k} = #{v}" 
      end
    end
  end

  io.close unless io_or_file.is_a? IO
end

.update!(file, data) ⇒ Object

Update the configuration file file with the data Hash, preserving the origin file layout, including comments. The spacial value :remove! comments out the ‘key = …’ line.



10
11
12
13
14
15
16
17
18
# File 'lib/dansguardian/updater.rb', line 10

def self.update!(file, data)
  tmp = Tempfile.new 'ruby_dansguardian_updater'
  update file, data do |line|
    tmp.puts line
  end
  tmp.close
  FileUtils.cp tmp.path, file
  tmp.unlink
end