2020-12-30 19:27:37 +01:00
""" Used by the make system to generate a rules.mk
"""
2021-01-31 21:46:00 +01:00
from pathlib import Path
from dotty_dict import dotty
2022-10-19 18:43:25 +02:00
from argcomplete . completers import FilesCompleter
2020-12-30 19:27:37 +01:00
from milc import cli
2022-10-19 18:43:25 +02:00
from qmk . info import info_json
2022-03-21 11:57:41 +01:00
from qmk . json_schema import json_load
2021-04-15 04:00:22 +02:00
from qmk . keyboard import keyboard_completer , keyboard_folder
2022-10-19 18:43:25 +02:00
from qmk . commands import dump_lines , parse_configurator_json
from qmk . path import normpath , FileType
2022-03-18 02:09:29 +01:00
from qmk . constants import GPL2_HEADER_SH_LIKE , GENERATED_HEADER_SH_LIKE
2020-12-30 19:27:37 +01:00
2021-01-31 21:46:00 +01:00
def process_mapping_rule ( kb_info_json , rules_key , info_dict ) :
""" Return the rules.mk line(s) for a mapping rule.
"""
if not info_dict . get ( ' to_c ' , True ) :
return None
info_key = info_dict [ ' info_key ' ]
2022-03-04 14:25:24 +01:00
key_type = info_dict . get ( ' value_type ' , ' raw ' )
2021-01-31 21:46:00 +01:00
try :
rules_value = kb_info_json [ info_key ]
except KeyError :
return None
2021-10-04 18:26:19 +02:00
if key_type in [ ' array ' , ' list ' ] :
2021-01-31 21:46:00 +01:00
return f ' { rules_key } ?= { " " . join ( rules_value ) } '
elif key_type == ' bool ' :
2022-02-27 13:39:24 +01:00
return f ' { rules_key } ?= { " yes " if rules_value else " no " } '
2021-01-31 21:46:00 +01:00
elif key_type == ' mapping ' :
return ' \n ' . join ( [ f ' { key } ?= { value } ' for key , value in rules_value . items ( ) ] )
2022-03-04 14:25:24 +01:00
elif key_type == ' str ' :
return f ' { rules_key } ?= " { rules_value } " '
2021-01-31 21:46:00 +01:00
return f ' { rules_key } ?= { rules_value } '
2020-12-30 19:27:37 +01:00
2020-12-30 20:21:18 +01:00
2022-10-19 18:43:25 +02:00
@cli.argument ( ' filename ' , nargs = ' ? ' , arg_only = True , type = FileType ( ' r ' ) , completer = FilesCompleter ( ' .json ' ) , help = ' A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed. ' )
2020-12-30 19:27:37 +01:00
@cli.argument ( ' -o ' , ' --output ' , arg_only = True , type = normpath , help = ' File to write to ' )
@cli.argument ( ' -q ' , ' --quiet ' , arg_only = True , action = ' store_true ' , help = " Quiet mode, only output error messages " )
2021-03-04 05:09:22 +01:00
@cli.argument ( ' -e ' , ' --escape ' , arg_only = True , action = ' store_true ' , help = " Escape spaces in quiet mode " )
2022-10-19 18:43:25 +02:00
@cli.argument ( ' -kb ' , ' --keyboard ' , arg_only = True , type = keyboard_folder , completer = keyboard_completer , help = ' Keyboard to generate rules.mk for. ' )
2021-08-18 22:52:41 +02:00
@cli.subcommand ( ' Used by the make system to generate rules.mk from info.json ' , hidden = True )
2020-12-30 19:27:37 +01:00
def generate_rules_mk ( cli ) :
""" Generates a rules.mk file from info.json.
"""
2022-10-21 03:21:17 +02:00
converter = None
2021-08-18 22:52:41 +02:00
# Determine our keyboard/keymap
2022-10-19 18:43:25 +02:00
if cli . args . filename :
user_keymap = parse_configurator_json ( cli . args . filename )
2022-10-21 03:21:17 +02:00
kb_info_json = dotty ( user_keymap . get ( ' config ' , { } ) )
converter = user_keymap . get ( ' converter ' , None )
2022-10-19 18:43:25 +02:00
elif cli . args . keyboard :
2021-08-18 22:52:41 +02:00
kb_info_json = dotty ( info_json ( cli . args . keyboard ) )
2022-10-19 18:43:25 +02:00
else :
cli . log . error ( ' You must supply a configurator export or `--keyboard`. ' )
cli . subcommands [ ' generate-rules-mk ' ] . print_help ( )
return False
2020-12-30 19:27:37 +01:00
2021-03-24 17:26:38 +01:00
info_rules_map = json_load ( Path ( ' data/mappings/info_rules.json ' ) )
2022-03-18 02:09:29 +01:00
rules_mk_lines = [ GPL2_HEADER_SH_LIKE , GENERATED_HEADER_SH_LIKE ]
2020-12-30 19:27:37 +01:00
2021-01-31 21:46:00 +01:00
# Iterate through the info_rules map to generate basic rules
for rules_key , info_dict in info_rules_map . items ( ) :
new_entry = process_mapping_rule ( kb_info_json , rules_key , info_dict )
if new_entry :
rules_mk_lines . append ( new_entry )
2020-12-01 21:52:02 +01:00
2021-01-31 21:46:00 +01:00
# Iterate through features to enable/disable them
2020-12-30 19:27:37 +01:00
if ' features ' in kb_info_json :
for feature , enabled in kb_info_json [ ' features ' ] . items ( ) :
2021-11-04 22:18:09 +01:00
feature = feature . upper ( )
enabled = ' yes ' if enabled else ' no '
rules_mk_lines . append ( f ' { feature } _ENABLE ?= { enabled } ' )
2020-12-30 19:27:37 +01:00
2021-08-17 00:33:30 +02:00
# Set SPLIT_TRANSPORT, if needed
if kb_info_json . get ( ' split ' , { } ) . get ( ' transport ' , { } ) . get ( ' protocol ' ) == ' custom ' :
rules_mk_lines . append ( ' SPLIT_TRANSPORT ?= custom ' )
# Set CUSTOM_MATRIX, if needed
if kb_info_json . get ( ' matrix_pins ' , { } ) . get ( ' custom ' ) :
if kb_info_json . get ( ' matrix_pins ' , { } ) . get ( ' custom_lite ' ) :
rules_mk_lines . append ( ' CUSTOM_MATRIX ?= lite ' )
else :
rules_mk_lines . append ( ' CUSTOM_MATRIX ?= yes ' )
2022-10-21 03:21:17 +02:00
if converter :
rules_mk_lines . append ( f ' CONVERT_TO ?= { converter } ' )
2020-12-30 19:27:37 +01:00
# Show the results
2022-03-18 02:09:29 +01:00
dump_lines ( cli . args . output , rules_mk_lines )
2020-12-30 19:27:37 +01:00
if cli . args . output :
if cli . args . quiet :
2021-03-04 05:09:22 +01:00
if cli . args . escape :
print ( cli . args . output . as_posix ( ) . replace ( ' ' , ' \\ ' ) )
else :
print ( cli . args . output )
2020-12-30 19:27:37 +01:00
else :
2021-01-31 21:46:00 +01:00
cli . log . info ( ' Wrote rules.mk to %s . ' , cli . args . output )