Skip to content

Instantly share code, notes, and snippets.

@gmcmillan
Created January 21, 2013 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmcmillan/4587903 to your computer and use it in GitHub Desktop.
Save gmcmillan/4587903 to your computer and use it in GitHub Desktop.
Simple parser for my.cnf/ini files without needing an external library.
class Config
# The path to the config file as a String.
attr_reader :file
# Attributes used while config is parsed.
#
# Example:
# [mysqld] # group
# param = val # param, val
#
attr_accessor :group, :param, :value
def initialize(file)
@file = file
end
def parse
config = {}
File.open(file).each_line do |line|
line.strip!
# Skip blank lines and lines starting with # and !
next if invalid_line?(line)
# Store which group in the config the line belongs to (e.g. [mysqld])
# Also create the new Hash for this group if it's nil.
if set_config_group(line)
config[group] = {} if config[group].nil?
next
end
# Capture the param/value of this line.
capture_param_and_value(line)
# In the rare cases where we're not within a group, add it to the
# root Hash, just to be safe.
if group.nil?
config[param] = value
else
config[group][param] = value
end
# Reset these attributes back to nil so they can be re-matched
# next iteration.
@param, @value = nil
end
config
end
private
# Capture param/value in line. If line is a param with no value, set the
# value to true.
def capture_param_and_value(line)
if line.match(/^\s*([\w\-]+)\s*[\s+|=]\s*[\"\']?([\w\-\/\.\:]+)[\s\"\']?\s*$/)
# Match normal "key = val" lines.
@param = $1
@value = $2
elsif line.match(/^\s*(\w|\-)+\s*$/)
# Match lines with a param but no value.
# e.g. federated, quick, skip-locking
@param = line
@value = true
end
end
# Set group attribute to match group one if it matches a
# group block (e.g. [mysqld])
def set_config_group(line)
@group = $1 if line.match(/^\[(.+?)\]/)
end
# Return true if line matches a blank line or # / (comments).
def invalid_line?(line)
line.match(/^\s*$/) or line.match(/^[\#|\!]+.*$/)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment