Class: S3TarBackup::IniParser

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

Instance Method Summary collapse

Constructor Details

#initialize(file_path, defaults = {}) ⇒ IniParser

Returns a new instance of IniParser.



8
9
10
# File 'lib/s3_tar_backup/ini_parser.rb', line 8

def initialize(file_path, defaults={})
  @file_path, @defaults = file_path, defaults
end

Instance Method Details

#[](arg) ⇒ Object



112
113
114
# File 'lib/s3_tar_backup/ini_parser.rb', line 112

def [](arg)
  get(arg)
end

#[]=(arg, value) ⇒ Object



160
161
162
# File 'lib/s3_tar_backup/ini_parser.rb', line 160

def []=(arg, value)
  set(arg, value)
end

#apply_defaults(defaults) ⇒ Object

Applies the defaults passed to the constructor



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/s3_tar_backup/ini_parser.rb', line 72

def apply_defaults(defaults)
  defaults.each do |key, default|
    section, key = key.match(/(.*)\.(.*)/)[1..2]

    if default.is_a?(Array)
      default_val, comment = default
    else
      default_val, comment = default, nil
    end

    @config[section] = {} unless @config.has_key?(section)
    set("#{section}.#{key}", default_val, comment)
  end
end

#eachObject



198
199
200
201
202
203
204
205
# File 'lib/s3_tar_backup/ini_parser.rb', line 198

def each
  @config.each_with_index do |section_key, section|
    section.each_with_index do |key, value|
      key_str = "#{section_key}#{key}"
      yield key_str, get(key_str)
    end
  end
end

#find_sections(pattern = /.*/) ⇒ Object



194
195
196
# File 'lib/s3_tar_backup/ini_parser.rb', line 194

def find_sections(pattern=/.*/)
  @config.select{ |k,v| k =~ pattern }
end

#get(arg, default = nil) ⇒ Object

Used to retrieve a config value, with an optional default. arg: The config key to get, in the form <section>.<key> default: The value to return if the key doesn’t exist. This function will use type information from self.defaults / default, if available. Example: config_object.get(‘section.key’, ‘default_value’)



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/s3_tar_backup/ini_parser.rb', line 121

def get(arg, default=nil)
  section, key = arg.match(/(.*)\.(.*)/)[1..2]
  section = section.to_sym
  key = key.to_sym

  unless @config.has_key?(section) && @config[section].has_key?(key)
    raise "Tried to access config key #{section}.#{key} which doesn't exist" if default.nil?
    return default
  end

  val = @config[section][key]
  # Is it one of the reserved keywords...?
  case val
  when 'True' then return true
  when 'False' then return false
  when 'None' then return nil
  end

  # Attempt to case... Is there a default?
  if default
    type = default.class
  elsif @defaults.has_key?("#{section}.#{key}")
    type = @defaults["#{section}.#{key}"].class
    # If default is of the form (value, comment)
    type = @defaults["#{section}.#{key}"][0].class if type.is_a?(Array)
  else
    type = nil
  end

  case type
  when Fixnum
    return val.to_i
  when Float
    return val.to_f
  else
    return val
  end
end

#has_section?(section) ⇒ Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/s3_tar_backup/ini_parser.rb', line 190

def has_section?(section)
  @config.has_key?(section.to_sym)
end

#loadObject

Loads the config from file, and parses it



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/s3_tar_backup/ini_parser.rb', line 13

def load
  if File.exists?(@file_path) && !File.directory?(@file_path)
    File.open(@file_path) do |f|
      @config, @comments = parse_config(f.readlines)
    end
  else
    @config, @comments = {}, {}
  end
  apply_defaults(@defaults)
  self # Allow chaining
end

#parse_config(config_lines) ⇒ Object

Parses a set of lines in a config file, turning them into sections and comments



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
# File 'lib/s3_tar_backup/ini_parser.rb', line 33

def parse_config(config_lines)
  # TODO get rid of all the {:before => [], :after => nil}
  config, comments = {}, {}
  section = nil
  next_comment = {:before => [], :after => nil}

  config_lines.each do |line|
    case line.chomp
    # Section
    when /^\[([\w\-]+)(?: "([\w\-]+)")?\]$/
      section = $1.chomp
      section << ".#{$2.chomp}" if $2
      section = section.to_sym
      config[section] = {} unless config.has_key?(section)
      comments[section] = {} unless comments.has_key?(section)
      next_comment = {:before => [], :after => nil}
      # key line
    when /^([\w\-]+)\s*=\s*([^;]*?)\s*(?:;\s+(.*))?$/
      raise "Config key before section" unless section
      key = $1.chomp.to_sym
      if config[section].has_key?(key)
        config[section][key] = [config[section][key]] unless config[section][key].is_a?(Array)
        config[section][key] << $2.chomp
      else
        config[section][key] = $2.chomp
      end
      # If we found a comment at the end of the line
      next_comment[:after] = $3 if $3
      comments[section][key] = next_comment unless next_comment == {:before => [], :after => nil}
      next_comment = {:before => [], :after => nil}
    when /;\s?(.*)/
      next_comment[:before] << $1
    end
  end

  [config, comments]
end

#render_config(comments = true) ⇒ Object

Takes the current config, and renders it



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/s3_tar_backup/ini_parser.rb', line 88

def render_config(comments=true)
  r = ''
  @config.each do |section_key, section|
    section_key_parts = section_key.to_s.split('.')
    if section_key_parts.count > 1
      r << "\n[#{section_key_parts.shift} \"#{section_key_parts.join(' ')}\"]\n\n"
    else
      r << "\n[#{section_key}]\n\n"
    end
    section.each do |key, values|
      values = [*values]
      comments_before, comments_after = '', ''
      if comments && @comments.include?(section_key) && @comments[section_key].include?(key)
        comments_before = @comments[section_key][key][:before].inject(''){ |s,v| s << "; #{v}\n" }
        comments_after = " ; #{@comments[section_key][key][:after]}" if @comments[section_key][key][:after]
      end
      r << comments_before
      r << values.map{ |value| "#{key} = #{value}" }.join("\n")
      r << comments_after << "\n\n"
    end
  end
  r.lstrip.rstrip
end

#saveObject

Saves the config to file



26
27
28
29
30
# File 'lib/s3_tar_backup/ini_parser.rb', line 26

def save
  File.open(@file_path, 'w') do |f|
    f.write(render_config)
  end
end

#set(arg, value, comments = nil) ⇒ Object

Used to set a config value, with optional comments. arg; The config key to set, in the form <section>.<key> comments: The comments to set, if any. If multiple lines are desired, they should be separated by “n” Example: config_object.set(‘section.key’, ‘value’, ‘This is the commentnExplaining section.key’)



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/s3_tar_backup/ini_parser.rb', line 168

def set(arg, value, comments=nil)
  section, key = arg.match(/(.*)\.(.*)/)[1..2]
  section = section.to_sym
  key = key.to_sym

  # Is it one of our special values?
  case value
  when true then value = 'True'
  when false then value = 'False'
  when nil then value = 'None'
  end

  @config[section] = {} unless @config.has_key?(section)
  @config[section][key] = value

  if comments
    comments = comments.split("\n")
    @comments[section] = {} unless @comments.has_key?(section)
    @comments[section][key] = {:before => comments, :after => nil}
  end
end