Browse Source

Change data driven "str" type to represent a quoted string literal (#16516)

* Change data driven "str" type to represent a quoted string literal

* Update docs
Ryan 3 years ago
parent
commit
ace0603f4f

+ 1 - 1
data/mappings/info_config.json

@@ -3,7 +3,7 @@
 {
     # Format:
     # <config.h key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
-    # value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping"
+    # value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping", "str", "raw"
     # to_json: Default `true`. Set to `false` to exclude this mapping from info.json
     # to_c: Default `true`. Set to `false` to exclude this mapping from config.h
     # warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places

+ 2 - 2
data/mappings/info_rules.json

@@ -3,7 +3,7 @@
 {
     # Format:
     # <rules.mk key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
-    # value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping"
+    # value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping", "str", "raw"
     # to_json: Default `true`. Set to `false` to exclude this mapping from info.json
     # to_c: Default `true`. Set to `false` to exclude this mapping from rules.mk
     # warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places
@@ -20,6 +20,6 @@
     "MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
     "NO_USB_STARTUP_CHECK": {"info_key": "usb.no_startup_check", "value_type": "bool"},
     "SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
-    "SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "value_type": "str", "to_c": false},
+    "SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
     "WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"}
 }

+ 3 - 2
docs/data_driven_config.md

@@ -44,7 +44,7 @@ In other cases you should group like options together in an `object`. This is pa
 In most cases you can add a simple mapping. These are maintained as JSON files in `data/mappings/info_config.json` and `data/mappings/info_rules.json`, and control mapping for `config.h` and `rules.mk`, respectively. Each mapping is keyed by the `config.h` or `rules.mk` variable, and the value is a hash with the following keys:
 
 * `info_key`: (required) The location within `info.json` for this value. See below.
-* `value_type`: (optional) Default `str`. The format for this variable's value. See below.
+* `value_type`: (optional) Default `raw`. The format for this variable's value. See below.
 * `to_json`: (optional) Default `true`. Set to `false` to exclude this mapping from info.json
 * `to_c`: (optional) Default `true`. Set to `false` to exclude this mapping from config.h
 * `warn_duplicate`: (optional) Default `true`. Set to `false` to turn off warning when a value exists in both places
@@ -57,7 +57,7 @@ Under the hood we use [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/)
 
 #### Value Types
 
-By default we treat all values as simple strings. If your value is more complex you can use one of these types to intelligently parse the data:
+By default we treat all values as unquoted "raw" data. If your value is more complex you can use one of these types to intelligently parse the data:
 
 * `array`: A comma separated array of strings
 * `array.int`: A comma separated array of integers
@@ -65,6 +65,7 @@ By default we treat all values as simple strings. If your value is more complex
 * `hex`: A number formatted as hex
 * `list`: A space separate array of strings
 * `mapping`: A hash of key/value pairs
+* `str`: A quoted string literal
 
 ### Add code to extract it
 

+ 7 - 2
lib/python/qmk/cli/generate/config_h.py

@@ -82,7 +82,7 @@ def generate_config_items(kb_info_json, config_h_lines):
 
     for config_key, info_dict in info_config_map.items():
         info_key = info_dict['info_key']
-        key_type = info_dict.get('value_type', 'str')
+        key_type = info_dict.get('value_type', 'raw')
         to_config = info_dict.get('to_config', True)
 
         if not to_config:
@@ -110,6 +110,11 @@ def generate_config_items(kb_info_json, config_h_lines):
                 config_h_lines.append(f'#ifndef {key}')
                 config_h_lines.append(f'#   define {key} {value}')
                 config_h_lines.append(f'#endif // {key}')
+        elif key_type == 'str':
+            config_h_lines.append('')
+            config_h_lines.append(f'#ifndef {config_key}')
+            config_h_lines.append(f'#   define {config_key} "{config_value}"')
+            config_h_lines.append(f'#endif // {config_key}')
         elif key_type == 'bcd_version':
             (major, minor, revision) = config_value.split('.')
             config_h_lines.append('')
@@ -200,7 +205,7 @@ def generate_config_h(cli):
         cli.args.output.parent.mkdir(parents=True, exist_ok=True)
         if cli.args.output.exists():
             cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak'))
-        cli.args.output.write_text(config_h)
+        cli.args.output.write_text(config_h, encoding='utf-8')
 
         if not cli.args.quiet:
             cli.log.info('Wrote info_config.h to %s.', cli.args.output)

+ 3 - 1
lib/python/qmk/cli/generate/rules_mk.py

@@ -19,7 +19,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
         return None
 
     info_key = info_dict['info_key']
-    key_type = info_dict.get('value_type', 'str')
+    key_type = info_dict.get('value_type', 'raw')
 
     try:
         rules_value = kb_info_json[info_key]
@@ -32,6 +32,8 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
         return f'{rules_key} ?= {"yes" if rules_value else "no"}'
     elif key_type == 'mapping':
         return '\n'.join([f'{key} ?= {value}' for key, value in rules_value.items()])
+    elif key_type == 'str':
+        return f'{rules_key} ?= "{rules_value}"'
 
     return f'{rules_key} ?= {rules_value}'
 

+ 8 - 2
lib/python/qmk/info.py

@@ -411,7 +411,7 @@ def _extract_config_h(info_data):
 
     for config_key, info_dict in info_config_map.items():
         info_key = info_dict['info_key']
-        key_type = info_dict.get('value_type', 'str')
+        key_type = info_dict.get('value_type', 'raw')
 
         try:
             if config_key in config_c and info_dict.get('to_json', True):
@@ -443,6 +443,9 @@ def _extract_config_h(info_data):
                 elif key_type == 'int':
                     dotty_info[info_key] = int(config_c[config_key])
 
+                elif key_type == 'str':
+                    dotty_info[info_key] = config_c[config_key].strip('"')
+
                 elif key_type == 'bcd_version':
                     major = int(config_c[config_key][2:4])
                     minor = int(config_c[config_key][4])
@@ -491,7 +494,7 @@ def _extract_rules_mk(info_data):
 
     for rules_key, info_dict in info_rules_map.items():
         info_key = info_dict['info_key']
-        key_type = info_dict.get('value_type', 'str')
+        key_type = info_dict.get('value_type', 'raw')
 
         try:
             if rules_key in rules and info_dict.get('to_json', True):
@@ -523,6 +526,9 @@ def _extract_rules_mk(info_data):
                 elif key_type == 'int':
                     dotty_info[info_key] = int(rules[rules_key])
 
+                elif key_type == 'str':
+                    dotty_info[info_key] = rules[rules_key].strip('"')
+
                 else:
                     dotty_info[info_key] = rules[rules_key]