Refactoring, cleanups and documentation
[git-stats.git] / src / git_stats / config.py
blob4e2cfe6848aa08664cb5484d08e325a0b70c1425
1 #!/usr/bin/env python
3 import os
5 from git import Repo
7 class Options():
8 """Options class
9 """
11 pass
13 def readAll(convert_camel_case=True):
14 """Reads all config files and returns the result
16 When a value is read in multiple times the one read in
17 the last is used. The following files are tried in the
18 listed order:
19 ~/.gitconfig
20 .git/config
21 config
22 """
24 paths = []
26 path = "~/.gitconfig"
27 path = os.path.expanduser(path)
28 paths.append(path)
30 repo = Repo(".")
31 path = os.path.join(repo.wd, '.git', 'config')
32 paths.append(path)
34 paths.append("config")
36 result = {}
38 # Check all the configuration files and parse them
39 for path in paths:
40 if not os.path.isfile(path):
41 continue
43 config = read(path, convert_camel_case)
45 # Add the found keys to our result
46 for key, value in config.iteritems():
47 result[key] = value
49 return result
51 def _readVerse(verse, config, convert_camel_case):
52 """Reads in a verse from a config file and stores the result in config
54 verse: The lines for the current verse, not including the header.
55 config: A dictionary to store the found configurations in.
56 convert_camel_case: Whether to convert camelCase words to dashed_form.
57 """
59 for line in verse:
60 # Remove spaces and newlines
61 stripline = line.lstrip().rstrip()
63 if stripline == line.rstrip() or not stripline:
64 break
66 # Extract the key:value pair
67 splitline = stripline.split(' = ')
68 key = splitline[0].rstrip()
69 value = splitline[1].lstrip()
71 # Try to convert to a number
72 try:
73 intval = int(value)
74 value = intval
75 except ValueError:
76 pass
78 # Try to convert boolean values
79 if value == "False":
80 value = False
82 if value == "True":
83 value = True
85 if value == "None":
86 value = None
88 # If desired, convert camelCase to dashed_form
89 if convert_camel_case and key.lower() != key:
90 dashed_form = ""
92 for c in key:
93 if c.isupper():
94 dashed_form += '_'
96 dashed_form += c.lower()
98 key = dashed_form
100 # Store the parsed and converted result
101 config[key] = value
103 def read(path, convert_camel_case=True):
104 """Reads in the specified file
106 Understands 'True', 'False', 'None' and integer values.
107 All camelCase keys are converted to dashed_form.
108 The file is expected to have the following format:
110 [GitStats]\n
111 [key = value\n]*
112 <any unindented or empty line>
115 Args:
116 path: The location of the file to read in
118 Returns: A dictionary with the key:value pairs specified in the file.
121 config = {}
123 file = open(path)
124 lines = file.readlines()
126 while True:
127 # Find our verse
128 try:
129 pos = lines.index("[GitStats]\n")
130 except ValueError:
131 return config
133 # Kick off the header
134 pos += 1
135 lines = lines[pos:]
137 # Read in this verse, updates config with the found configurations
138 _readVerse(lines, config, convert_camel_case)
140 return config
142 def extractOptions(options, options_list):
143 """Extracts options and returns the result
145 The options are extracted from the specified options and
146 from the 'config' file.
149 opts = readAll()
151 result = Options()
153 for opt in options_list:
154 if getattr(options, opt, None) == None:
155 val = opts.get(opt, None)
156 else:
157 val = getattr(options, opt)
159 if val == None and getattr(result, opt, None) != None:
160 continue
162 setattr(result, opt, val)
164 return result
166 def main(args):
167 """Parses all config files and prints the result
169 Runs once with convert_camel_case on, and once with it off.
171 Params:
172 args: Not used
175 result = readAll()
177 print("convert_camel_case is ON:")
178 for key, value in result.iteritems():
179 print(str(key) + ": " + str(value))
181 result = readAll(False)
183 print("")
184 print("convertCamelCase is OFF:")
185 for key, value in result.iteritems():
186 print(str(key) + ": " + str(value))
188 if __name__ == '__main__':
189 import sys
190 main(sys.argv)