aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python/qmk/makefile.py
blob: dc498adc8fba2c8efef99fb003574741cc8f9513 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
""" Functions for working with Makefiles
"""
import os
import glob
import re

import qmk.path
from qmk.errors import NoSuchKeyboardError

def parse_rules_mk(file_path):
    """ Parse a rules.mk file

    Args:
        file_path: path to the rules.mk file

    Returns:
        a dictionary with the file's content
    """
    # regex to match lines uncommented lines and get the data
    # group(1) = option's name
    # group(2) = operator (eg.: '=', '+=')
    # group(3) = value(s)
    rules_mk_regex = re.compile(r"^\s*(\w+)\s*([\?\:\+\-]?=)\s*(\S.*?)(?=\s*(\#|$))")
    mk_content = qmk.path.unicode_lines(file_path)
    parsed_file = dict()
    for line in mk_content:
        found = rules_mk_regex.search(line)
        if found:
            parsed_file[found.group(1)] = dict(operator = found.group(2), value = found.group(3))
    return parsed_file

def merge_rules_mk_files(base, revision):
    """ Merge a keyboard revision's rules.mk file with
    the 'base' rules.mk file

    Args:
        base: the base rules.mk file's content as dictionary
        revision: the revision's rules.mk file's content as dictionary

    Returns:
        a dictionary with the merged content
    """
    return {**base, **revision}

def get_rules_mk(keyboard, revision = ""):
    """ Get a rules.mk for a keyboard

    Args:
        keyboard: name of the keyboard
        revision: revision of the keyboard

    Returns:
        a dictionary with the content of the rules.mk file
    """
    base_path = os.path.join(os.getcwd(), "keyboards", keyboard) + os.path.sep
    rules_mk = dict()
    if os.path.exists(base_path + os.path.sep + revision):
        rules_mk_path_wildcard = os.path.join(base_path, "**", "rules.mk")
        rules_mk_regex = re.compile(r"^" + base_path + "(?:" + revision + os.path.sep + ")?rules.mk")
        paths = [path for path in glob.iglob(rules_mk_path_wildcard, recursive = True) if rules_mk_regex.search(path)]
        for file_path in paths:
            rules_mk[revision if revision in file_path else "base"] = parse_rules_mk(file_path)
    else:
        raise NoSuchKeyboardError("The requested keyboard and/or revision does not exist.")

    # if the base or the revision directory does not contain a rules.mk
    if len(rules_mk) == 1:
        rules_mk = rules_mk[revision]
    # if both directories contain rules.mk files
    elif len(rules_mk) == 2:
        rules_mk = merge_rules_mk_files(rules_mk["base"], rules_mk[revision])
    return rules_mk