diff options
| author | sommersoft <sommersoft@gmail.com> | 2019-07-27 09:15:37 -0500 |
|---|---|---|
| committer | sommersoft <sommersoft@gmail.com> | 2019-07-27 09:15:37 -0500 |
| commit | a184380dc9a01a88ecb3735d5fbf48e955f2546f (patch) | |
| tree | 891ea101c9fe4c1b7663c9576dce6e6a9b995359 /docs/shared_bindings_matrix.py | |
| parent | 45a54c3fd75d4ac14b46d150cf9b2a69f8f0bb88 (diff) | |
add port-wide config parsing; add modules-by-board function
Diffstat (limited to 'docs/shared_bindings_matrix.py')
| -rw-r--r-- | docs/shared_bindings_matrix.py | 148 |
1 files changed, 128 insertions, 20 deletions
diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index 59b67b7b2..694a60942 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -29,6 +29,45 @@ import re SUPPORTED_PORTS = ["atmel-samd", "nrf"] +def parse_port_config(contents, chip_keyword=None): + """ Compile a dictionary of port-wide module configs, which may + be categorized by chipset. + """ + chip_fam = "all" + ifeq_found = False + port_config_results = {"all": []} + + chip_pattern = "" + if chip_keyword: + chip_pattern = ( + re.compile("(?<=ifeq\s\(\$\({}\)\,)(\w+)".format(chip_keyword)) + ) + + for line in contents: + if chip_keyword: + if not ifeq_found: + check_ifeq = chip_pattern.search(line) + if check_ifeq: + ifeq_found = True + chip_fam = check_ifeq.group(1) + print("found chip:", chip_fam) + else: + ifeq_found = False + chip_fam = "all" + else: + if "endif" in line: + ifeq_found = False + chip_fam = "all" + + if "CIRCUITPY_" in line: + if chip_fam in port_config_results: + port_config_results[chip_fam].append(line.rstrip("\n")) + else: + port_config_results[chip_fam] = [line.rstrip("\n")] + + #print(port_config_results) + return port_config_results + def get_shared_bindings(): """ Get a list of modules in shared-bindings based on folder names """ @@ -45,13 +84,15 @@ def read_mpconfig(): return configs -def build_module_map(modules, configs): +def build_module_map(): """ Establish the base of the JSON file, based on the contents from `configs`. Base will contain module names, if they're part of the `FULL_BUILD`, or their default value (0 | 1). """ base = dict() + modules = get_shared_bindings() + configs = read_mpconfig() full_build = False for module in modules: full_name = module @@ -71,36 +112,67 @@ def build_module_map(modules, configs): "name": full_name, "full_build": str(full_build), "default_value": default_val, - "excluded": [] + "excluded": {} } - return get_excluded_boards(base) + return base def get_excluded_boards(base): """ Cycles through each board's `mpconfigboard.mk` file to determine if each module is included or not. Boards are selected by existence in a port listed in `SUPPORTED_PORTS` (e.g. `/port/nrf/feather_52840`) + + Boards are further categorized by their respective chipset (SAMD21, + SAMD51, nRF52840, etc.) """ modules = list(base.keys()) + + re_board_chip = None + chip_keyword = None for port in SUPPORTED_PORTS: - port_dir = "ports/{}/boards".format(port) - for entry in os.scandir(port_dir): + # each port appears to use its own define for the chipset + if port in ["atmel-samd"]: + re_board_chip = re.compile("CHIP_FAMILY\s=\s(\w+)") + chip_keyword = "CHIP_FAMILY" + elif port in ["nrf"]: + re_board_chip = re.compile("MCU_VARIANT\s=\s(\w+)") + + port_dir = "ports/{}".format(port) + + port_config_contents = "" + with open(os.path.join(port_dir, "mpconfigport.mk")) as port_config: + port_config_contents = port_config.readlines() + port_config = parse_port_config(port_config_contents, chip_keyword) + + for entry in os.scandir(os.path.join(port_dir, "boards")): if not entry.is_dir(): continue + contents = "" board_dir = os.path.join(entry.path, "mpconfigboard.mk") - #print(board_dir) with open(board_dir) as board: contents = board.read() + + board_chip = re_board_chip.search(contents) + #print(entry.name, board_chip.group(1)) + if not board_chip: + board_chip = "Unknown Chip" + else: + board_chip = board_chip.group(1) + + # add port_config results to contents + contents += "\n" + "\n".join(port_config["all"]) + if board_chip in port_config: + contents += "\n" + "\n".join(port_config[board_chip]) + for module in modules: + board_is_excluded = False # check if board uses `SMALL_BUILD`. if yes, and current # module is marked as `FULL_BUILD`, board is excluded small_build = re.search("CIRCUITPY_SMALL_BUILD = 1", contents) if small_build and base[module]["full_build"] == "1": - base[module]["excluded"].append(entry.name) - continue - + board_is_excluded = True # check if module is specifically disabled for this board re_pattern = "CIRCUITPY_{}\s=\s(\w)".format(module.upper()) find_module = re.search(re_pattern, contents) @@ -108,18 +180,54 @@ def get_excluded_boards(base): # check if default inclusion is off ('0'). if the board doesn't # have it explicitly enabled, its excluded. if base[module]["default_value"] == "0": - base[module]["excluded"].append(entry.name) - continue - if (find_module.group(1) == "0" and - find_module.group(1) != base[module]["default_value"]): - base[module]["excluded"].append(entry.name) - + board_is_excluded = True + else: + if (find_module.group(1) == "0" and + find_module.group(1) != base[module]["default_value"]): + board_is_excluded = True + + if board_is_excluded: + if board_chip in base[module]["excluded"]: + base[module]["excluded"][board_chip].append(entry.name) + else: + base[module]["excluded"][board_chip] = [entry.name] + #print(json.dumps(base, indent=2)) return base -def support_matrix(): - modules = get_shared_bindings() - configs = read_mpconfig() - base = build_module_map(sorted(modules), configs) +def support_matrix_excluded_boards(): + """ Compiles a list of available modules, and which board definitions + do not include them. + """ + base = build_module_map() - return base + return get_excluded_boards(base) + +def support_matrix_by_board(): + """ Compiles a list of the available core modules available for each + board. + """ + base = build_module_map() + base_with_exclusions = get_excluded_boards(base) + + boards = dict() + for port in SUPPORTED_PORTS: + port_dir = "ports/{}/boards".format(port) + for entry in os.scandir(port_dir): + if not entry.is_dir(): + continue + board_modules = [] + for module in base_with_exclusions.keys(): + #print(module) + board_has_module = True + if base_with_exclusions[module]["excluded"]: + for port in base_with_exclusions[module]["excluded"].values(): + #print(port) + if entry.name in port: + board_has_module = False + + if board_has_module: + board_modules.append(base_with_exclusions[module]["name"]) + boards[entry.name] = sorted(board_modules) + + return boards |
