summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2023-05-22 06:31:04 +0300
committerEvgeny Zinoviev <me@ch1p.io>2023-05-22 06:31:04 +0300
commit786e8078e4802748e7bb60920dffa862135ae946 (patch)
treed42ce78b9a58e43806b3c3d1ae8810c8f6af3cbf
parent7706c3c37e2042d1b36744aae45c901f475c7c9c (diff)
pio_ini.py: platformio.ini generation improvements
-rw-r--r--src/home/pio/products.py15
-rwxr-xr-xsrc/pio_ini.py98
2 files changed, 96 insertions, 17 deletions
diff --git a/src/home/pio/products.py b/src/home/pio/products.py
index 4cb3cf2..7649078 100644
--- a/src/home/pio/products.py
+++ b/src/home/pio/products.py
@@ -31,13 +31,17 @@ def get_products():
def platformio_ini(product_config: dict,
target: str,
- node_id: str,
+ # node_id: str,
+ build_specific_defines: dict,
+ build_specific_defines_enums: list[str],
platform: str,
framework: str = 'arduino',
upload_port: str = '/dev/ttyUSB0',
monitor_speed: int = 115200,
debug=False,
debug_network=False) -> str:
+ node_id = build_specific_defines['CONFIG_NODE_ID']
+
# defines
defines = {
**product_config['common_defines'],
@@ -60,6 +64,9 @@ def platformio_ini(product_config: dict,
defines['DEBUG_ESP_SSL'] = True
defines['DEBUG_ESP_PORT'] = 'Serial'
build_type = 'debug'
+ if build_specific_defines:
+ for k, v in build_specific_defines.items():
+ defines[k] = v
defines = OrderedDict(sorted(defines.items(), key=lambda t: t[0]))
# libs
@@ -93,13 +100,15 @@ def platformio_ini(product_config: dict,
if defines:
for name, value in defines.items():
buf.write(f' -D{name}')
+ is_enum = name in build_specific_defines_enums
if type(value) is not bool:
buf.write('=')
if type(value) is str:
- buf.write('"\\"')
+ if not is_enum:
+ buf.write('"\\"')
value = value.replace('"', '\\"')
buf.write(f'{value}')
- if type(value) is str:
+ if type(value) is str and not is_enum:
buf.write('"\\"')
buf.write('\n')
buf.write(f' -I../common/include')
diff --git a/src/pio_ini.py b/src/pio_ini.py
index 2d9c7c6..19dd707 100755
--- a/src/pio_ini.py
+++ b/src/pio_ini.py
@@ -1,7 +1,9 @@
#!/usr/bin/env python3
import os
import yaml
+import re
+from pprint import pprint
from argparse import ArgumentParser, ArgumentError
from home.pio import get_products, platformio_ini
from home.pio.exceptions import ProductConfigNotFoundError
@@ -19,22 +21,74 @@ def get_config(product: str) -> dict:
return yaml.safe_load(f)
+def bsd_walk(product_config: dict,
+ f: callable):
+ try:
+ for define_name, define_extra_params in product_config['build_specific_defines'].items():
+ define_name = re.sub(r'^CONFIG_', '', define_name)
+ kwargs = {}
+ if isinstance(define_extra_params, dict):
+ kwargs = define_extra_params
+ f(define_name, **kwargs)
+ except KeyError:
+ pass
+
+
+# 'bsd' means 'build_specific_defines'
+def bsd_parser(product_config: dict,
+ parser: ArgumentParser):
+ def f(define_name, **kwargs):
+ arg_kwargs = {}
+ define_name = define_name.lower().replace('_', '-')
+
+ if 'type' in kwargs:
+ if kwargs['type'] in ('str', 'enum'):
+ arg_kwargs['type'] = str
+ if kwargs['type'] == 'enum' and 'list_config_key' in kwargs:
+ if not isinstance(product_config[kwargs['list_config_key']], list):
+ raise TypeError(f'product_config[{kwargs["list_config_key"]}] enum is not list')
+ if not product_config[kwargs['list_config_key']]:
+ raise ValueError(f'product_config[{kwargs["list_config_key"]}] enum cannot be empty')
+ arg_kwargs['choices'] = product_config[kwargs['list_config_key']]
+ if isinstance(product_config[kwargs['list_config_key']][0], int):
+ arg_kwargs['type'] = int
+ elif kwargs['type'] == 'int':
+ arg_kwargs['type'] = int
+ else:
+ raise TypeError(f'unsupported type {kwargs["type"]} for define {define_name}')
+ else:
+ arg_kwargs['action'] = 'store_true'
+
+ parser.add_argument(f'--{define_name}', required=True, **arg_kwargs)
+
+ bsd_walk(product_config, f)
+
+
+def bsd_get(product_config: dict,
+ arg: object):
+ defines = {}
+ enums = []
+ def f(define_name, **kwargs):
+ attr_name = define_name.lower()
+ attr_value = getattr(arg, attr_name)
+ if 'type' in kwargs:
+ if kwargs['type'] == 'enum':
+ enums.append(f'CONFIG_{define_name}')
+ defines[f'CONFIG_{define_name}'] = f'HOMEKIT_{attr_value.upper()}'
+ return
+ defines[f'CONFIG_{define_name}'] = str(attr_value)
+ bsd_walk(product_config, f)
+ return defines, enums
+
+
if __name__ == '__main__':
products = get_products()
- parser = ArgumentParser()
- parser.add_argument('--product', type=str, choices=products,
- help='PIO product name')
- parser.add_argument('--target', type=str, required=True,
- help='PIO build target')
- parser.add_argument('--node-id', type=str)
- parser.add_argument('--platform', default='espressif8266', type=str)
- parser.add_argument('--framework', default='arduino', type=str)
- parser.add_argument('--upload-port', default='/dev/ttyUSB0', type=str)
- parser.add_argument('--monitor-speed', default=115200)
- parser.add_argument('--debug', action='store_true')
- parser.add_argument('--debug-network', action='store_true')
- arg = parser.parse_args()
+ # first, get the product
+ product_parser = ArgumentParser(add_help=False)
+ product_parser.add_argument('--product', type=str, choices=products, required=True,
+ help='PIO product name')
+ arg, _ = product_parser.parse_known_args()
if not arg.product:
product = os.path.basename(os.path.realpath(os.getcwd()))
if product not in products:
@@ -43,12 +97,28 @@ if __name__ == '__main__':
product = arg.product
product_config = get_config(product)
+
+ # then everythingm else
+ parser = ArgumentParser(parents=[product_parser])
+ parser.add_argument('--target', type=str, required=True, choices=product_config['targets'],
+ help='PIO build target')
+ parser.add_argument('--platform', default='espressif8266', type=str)
+ parser.add_argument('--framework', default='arduino', type=str)
+ parser.add_argument('--upload-port', default='/dev/ttyUSB0', type=str)
+ parser.add_argument('--monitor-speed', default=115200)
+ parser.add_argument('--debug', action='store_true')
+ parser.add_argument('--debug-network', action='store_true')
+ bsd_parser(product_config, parser)
+ arg = parser.parse_args()
+
if arg.target not in product_config['targets']:
raise ArgumentError(None, f'target {arg.target} not found for product {product}')
+ bsd, bsd_enums = bsd_get(product_config, arg)
ini = platformio_ini(product_config=product_config,
target=arg.target,
- node_id=arg.node_id,
+ build_specific_defines=bsd,
+ build_specific_defines_enums=bsd_enums,
platform=arg.platform,
framework=arg.framework,
upload_port=arg.upload_port,