pio_ini.py: platformio.ini generation improvements

This commit is contained in:
Evgeny Zinoviev 2023-05-22 06:31:04 +03:00
parent 7706c3c37e
commit 786e8078e4
2 changed files with 96 additions and 17 deletions

View File

@ -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')

View File

@ -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,