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: Issue 6552 - Support arbitrary manifest values Created April 11, 2018, 9:42 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') | tests/metadata.chrome » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chainedconfigparser.py
diff --git a/chainedconfigparser.py b/chainedconfigparser.py
index ce26b04b50e175e1cbd99a772f2a589acd1ac64c..0eaa280670fdce9732c92b79fa75c5edaead3cdd 100644
--- a/chainedconfigparser.py
+++ b/chainedconfigparser.py
@@ -157,6 +157,78 @@ class ChainedConfigParser(ConfigParser.SafeConfigParser):
raise ConfigParser.NoSectionError(section)
raise ConfigParser.NoOptionError(option, section)
+ def as_json_object(self, section):
+ r"""Parse a given section into a JSON object.
+
+ Parse arbitrary key/value pairs from 'section' of the current
+ configuration into a nested JSON object.
+
+ The following rules need to be considered:
+
+ * An option's key may be declared as a series of nested dictionary keys,
+ seperated by '.'.
+ * An option's key must end with '[]', to mark this option as an array
+ * When an option is marked as an array, no other nested objects may
+ follow
+ * An array is expandable by the ConfigParser's '+=' token.
+ * Values may be marked as special types by appending '\{code}':
+ * \b - boolean
+ * \i - integer
+ * \f - float
+
+ Example:
+
+ {
+ "good": false,
+ "bar": {
+ "baz": ["bar", "bazinga"]
+ foo = foo },
+ bar.baz[] = bar "is": {
+ baz.foo = a "integer": 1,
+ baz.z[] = b "float": 1.4
+ bar.baz[] += bazinga ==> },
+ bad = true\b "baz": {
+ good = f\b "foo": "a",
+ is.integer = 1\i "z": ["b"]
+ is.float = 1.4\f },
+ "bad": true
+ "foo": "foo"
+ }
+ """
+ def parse_values(v):
+ import distutils
+ if isinstance(v, list):
+ return [parse_values(x) for x in v]
+
+ mapping = {
+ '\\b': lambda x: bool(distutils.util.strtobool(x)),
+ '\\i': int,
+ '\\f': float,
+ }
+ if '\\' in v:
+ return mapping[v[-2:]](v[:-2])
+ return v
Sebastian Noack 2018/04/12 12:19:23 * I cannot think of any relevant manifest key wher
tlucas 2018/04/12 13:47:39 I do not fully oppose your thoughts, but what abou
Sebastian Noack 2018/04/12 14:39:29 I was thinking about the version number, but its n
tlucas 2018/04/13 09:14:59 Done.
+
+ def setdefault_recursive(target, arr):
+ if len(arr) == 2:
+ target.setdefault(arr[0], parse_values(arr[1]))
+ else:
+ current = target.setdefault(arr[0], {})
Sebastian Noack 2018/04/12 12:19:23 You might want to use an OrderedDict to make sure
tlucas 2018/04/12 13:47:38 Good point, done.
+ setdefault_recursive(current, arr[1:])
+
+ data = self.items(section)
+ result = {}
Sebastian Noack 2018/04/12 12:19:23 Same here.
tlucas 2018/04/12 13:47:38 See above, done.
+
+ for k, v in data:
+ is_array = k.endswith('[]')
+
+ sub_keys = (k if not is_array else k[:-2]).split('.')
+ value = v.split() if is_array else v
Sebastian Noack 2018/04/12 12:19:23 It seems the logic here can be simplified: if k
tlucas 2018/04/12 13:47:39 Done.
+
+ setdefault_recursive(result, sub_keys + [value])
+
+ return result
+
def readfp(self, fp, filename=None):
raise NotImplementedError
« no previous file with comments | « no previous file | packagerChrome.py » ('j') | tests/metadata.chrome » ('J')

Powered by Google App Engine
This is Rietveld