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: NOCHANGE rebase against current master (30b4e987f025) Created April 18, 2018, 2:35 p.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..9691174ae5853a28b9f06402f2003b79447599a0 100644
--- a/chainedconfigparser.py
+++ b/chainedconfigparser.py
@@ -6,6 +6,7 @@ import os
import io
import ConfigParser
from StringIO import StringIO
+from collections import OrderedDict
class Item(tuple):
@@ -157,6 +158,79 @@ 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 `number` or `bool` by prefixing them
+ accordingly:
+ * bool:<value>
+ * number:<value>
+
+ Example:
+
+ {
+ "good": false,
+ "bar": {
+ "baz": ["bar", "bazinga"]
+ foo = foo },
+ bar.baz[] = bar "is": {
+ baz.foo = a "integer": 1,
+ baz.z[] = b bool:true "float": 1.4
+ bar.baz[] += bazinga ==> },
+ bad = bool:true "baz": {
+ good = bool:false "foo": "a",
+ is.integer = number:1 "z": ["b", true]
+ is.float = number:1.4 },
+ "bad": true
+ "foo": "foo"
+ }
+ """
+ def parse_values(v):
+ if isinstance(v, list):
+ return [parse_values(x) for x in v]
+
+ if v.startswith('number:'):
+ v = v.split(':', 1)[1]
+ try:
+ v = int(v)
+ except ValueError:
+ v = float(v)
+ elif v == 'bool:true':
+ v = True
+ elif v == 'bool:false':
+ v = False
+ return v
+
+ def setdefault_recursive(target, arr):
+ if len(arr) == 2:
+ target.setdefault(arr[0], parse_values(arr[1]))
+ else:
+ current = target.setdefault(arr[0], OrderedDict())
+ setdefault_recursive(current, arr[1:])
+
+ data = self.items(section)
+ result = OrderedDict()
+
+ for k, v in data:
+ if k.endswith('[]'):
+ k = k[:-2]
+ v = v.split()
+
+ setdefault_recursive(result, k.split('.') + [v])
+
+ return result
+
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