Class: S3TarBackup::IniParser

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of IniParser.



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

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

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



3
4
5
# File 'lib/s3_tar_backup/ini_parser.rb', line 3

def file_path
  @file_path
end

Instance Method Details

#[](arg) ⇒ Object



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

def [](arg)
  get(arg)
end

#[]=(arg, value) ⇒ Object



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

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

#apply_defaults(defaults) ⇒ Object

Applies the defaults passed to the constructor



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

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



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

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



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

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’)



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

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 Integer
    return val.to_i
  when Float
    return val.to_f
  else
    return val
  end
end

#has_section?(section) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#loadObject

Loads the config from file, and parses it



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

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



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

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



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

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



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

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’)



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

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