Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: chainedconfigparser.py

Issue 29743581: Issue 6552 - Support arbitrary manifest values (Closed) Base URL: https://hg.adblockplus.org/buildtools/file/a3db4a1a49e8
Patch Set: Created April 19, 2018, 9:59 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | packagerChrome.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chainedconfigparser.py
diff --git a/chainedconfigparser.py b/chainedconfigparser.py
index ce26b04b50e175e1cbd99a772f2a589acd1ac64c..504ecc3303f214d85ede2da3a325616d167670dd 100644
--- a/chainedconfigparser.py
+++ b/chainedconfigparser.py
@@ -93,15 +93,15 @@ class ChainedConfigParser(ConfigParser.SafeConfigParser):
except ConfigParser.NoOptionError:
raise DiffForUnknownOptionError(option, section)
- orig_values = orig_value.split()
- diff_values = value.split()
+ orig_values = orig_value.splitlines()
+ diff_values = value.splitlines()
if is_addition:
new_values = orig_values + [v for v in diff_values if v not in orig_values]
else:
new_values = [v for v in orig_values if v not in diff_values]
- value = ' '.join(new_values)
+ value = '\n'.join(new_values)
return is_diff, option, value
@@ -157,6 +157,79 @@ class ChainedConfigParser(ConfigParser.SafeConfigParser):
raise ConfigParser.NoSectionError(section)
raise ConfigParser.NoOptionError(option, section)
+ def section_as_dict(self, section, base):
+ """Parse a given section into a dictionary.
+
+ Parse arbitrary key/value pairs from 'section' of the current
+ configuration into a dictionary and deep merge it into `base`.
+
+ The following rules need to be considered:
+
+ * An option's key may be declared as a series of nested dictionary keys,
+ seperated by '.'.
+ * Declaring an option's value in a new line (even if only one is given)
+ will define the option's value as an array.
Sebastian Noack 2018/04/19 10:50:56 Nit: Talking about "arrays" made sense initially w
tlucas 2018/04/19 11:08:13 Done.
+ * When an option's value is defined as an array, no other nested
+ objects may follow.
+ * An array is expandable by the ConfigParser's '+=' token (Note: A
+ previously declared string will be converted into an array).
+ * Values may be marked as `number` or `bool` by prefixing them
+ accordingly (this also applies to values in an array):
+ * bool:<value>
+ * number:<value>
+
+ Example:
+ {
+ foo = foo "foo": "foo",
+ asd = "asd": ["asd"],
+ asd "bar": {
Sebastian Noack 2018/04/19 10:50:57 Nit: For consistency, we might want to use two spa
tlucas 2018/04/19 11:08:14 Done.
+ bar.baz = a "baz": ["a", "c", "d"]
+ baz.foo = a },
+ baz.z = "baz": {
+ bar "foo": "a",
+ bool:true ===> "z": ["bar", true]
+ bar.baz += },
+ c "bad": true,
+ d "good": false,
+ bad = bool:true "is": {
+ good = bool:false "integer": 1,
+ is.integer = number:1 "float": 1.4
+ is.float = number:1.4 }
+ }
+ """
+ def parse_values(v):
Sebastian Noack 2018/04/19 10:50:57 Nit; since this function is only called with a sin
tlucas 2018/04/19 11:08:13 Done.
+ if isinstance(v, list):
+ return [parse_values(x) for x in v]
Sebastian Noack 2018/04/19 10:50:57 This code path can be removed now, since we no lon
tlucas 2018/04/19 11:08:14 Done.
+
+ if v.startswith('number:'):
+ v = v.split(':', 1)[1]
+ try:
+ return int(v)
+ except ValueError:
+ return float(v)
+ if v == 'bool:true':
+ return True
+ if v == 'bool:false':
+ return False
+ return v
+
+ data = self.items(section)
Sebastian Noack 2018/04/19 10:50:56 Nit: this variable is only used once, perhaps inli
tlucas 2018/04/19 11:08:14 Done. One note: Not catching a NoSectionError her
tlucas 2018/04/19 11:45:15 Done.
+
+ for k, v in data:
+
Sebastian Noack 2018/04/19 10:50:58 Nit: Is the blank line here intended? It looks wei
tlucas 2018/04/19 11:08:15 Done.
+ parents = k.split('.')
+ tail = parents.pop()
+ current = base
+ for name in parents:
+ current = base.setdefault(name, {})
+
+ if '\n' in v:
+ current[tail] = [parse_values(x) for x in v.splitlines() if x]
+ else:
+ current[tail] = parse_values(v)
+
+ return base
Sebastian Noack 2018/04/19 10:50:57 Nit: Returning the dictionary seems redundant. It'
tlucas 2018/04/19 11:08:14 I wouldn't mind either solution - but we also migh
Sebastian Noack 2018/04/19 11:12:41 That is exactly what I said. My suggestions above
tlucas 2018/04/19 11:45:15 Done.
+
def readfp(self, fp, filename=None):
raise NotImplementedError
« no previous file with comments | « no previous file | packagerChrome.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld