1*da0073e9SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Workerfrom pathlib import Path 4*da0073e9SAndroid Build Coastguard Worker 5*da0073e9SAndroid Build Coastguard Worker 6*da0073e9SAndroid Build Coastguard Workertry: 7*da0073e9SAndroid Build Coastguard Worker # VS Code settings allow comments and trailing commas, which are not valid JSON. 8*da0073e9SAndroid Build Coastguard Worker import json5 as json # type: ignore[import] 9*da0073e9SAndroid Build Coastguard Worker 10*da0073e9SAndroid Build Coastguard Worker HAS_JSON5 = True 11*da0073e9SAndroid Build Coastguard Workerexcept ImportError: 12*da0073e9SAndroid Build Coastguard Worker import json # type: ignore[no-redef] 13*da0073e9SAndroid Build Coastguard Worker 14*da0073e9SAndroid Build Coastguard Worker HAS_JSON5 = False 15*da0073e9SAndroid Build Coastguard Worker 16*da0073e9SAndroid Build Coastguard Worker 17*da0073e9SAndroid Build Coastguard WorkerROOT_FOLDER = Path(__file__).absolute().parent.parent 18*da0073e9SAndroid Build Coastguard WorkerVSCODE_FOLDER = ROOT_FOLDER / ".vscode" 19*da0073e9SAndroid Build Coastguard WorkerRECOMMENDED_SETTINGS = VSCODE_FOLDER / "settings_recommended.json" 20*da0073e9SAndroid Build Coastguard WorkerSETTINGS = VSCODE_FOLDER / "settings.json" 21*da0073e9SAndroid Build Coastguard Worker 22*da0073e9SAndroid Build Coastguard Worker 23*da0073e9SAndroid Build Coastguard Worker# settings can be nested, so we need to recursively update the settings. 24*da0073e9SAndroid Build Coastguard Workerdef deep_update(d: dict, u: dict) -> dict: # type: ignore[type-arg] 25*da0073e9SAndroid Build Coastguard Worker for k, v in u.items(): 26*da0073e9SAndroid Build Coastguard Worker if isinstance(v, dict): 27*da0073e9SAndroid Build Coastguard Worker d[k] = deep_update(d.get(k, {}), v) 28*da0073e9SAndroid Build Coastguard Worker elif isinstance(v, list): 29*da0073e9SAndroid Build Coastguard Worker d[k] = d.get(k, []) + v 30*da0073e9SAndroid Build Coastguard Worker else: 31*da0073e9SAndroid Build Coastguard Worker d[k] = v 32*da0073e9SAndroid Build Coastguard Worker return d 33*da0073e9SAndroid Build Coastguard Worker 34*da0073e9SAndroid Build Coastguard Worker 35*da0073e9SAndroid Build Coastguard Workerdef main() -> None: 36*da0073e9SAndroid Build Coastguard Worker recommended_settings = json.loads(RECOMMENDED_SETTINGS.read_text()) 37*da0073e9SAndroid Build Coastguard Worker try: 38*da0073e9SAndroid Build Coastguard Worker current_settings_text = SETTINGS.read_text() 39*da0073e9SAndroid Build Coastguard Worker except FileNotFoundError: 40*da0073e9SAndroid Build Coastguard Worker current_settings_text = "{}" 41*da0073e9SAndroid Build Coastguard Worker 42*da0073e9SAndroid Build Coastguard Worker try: 43*da0073e9SAndroid Build Coastguard Worker current_settings = json.loads(current_settings_text) 44*da0073e9SAndroid Build Coastguard Worker except ValueError as ex: # json.JSONDecodeError is a subclass of ValueError 45*da0073e9SAndroid Build Coastguard Worker if HAS_JSON5: 46*da0073e9SAndroid Build Coastguard Worker raise SystemExit("Failed to parse .vscode/settings.json.") from ex 47*da0073e9SAndroid Build Coastguard Worker raise SystemExit( 48*da0073e9SAndroid Build Coastguard Worker "Failed to parse .vscode/settings.json. " 49*da0073e9SAndroid Build Coastguard Worker "Maybe it contains comments or trailing commas. " 50*da0073e9SAndroid Build Coastguard Worker "Try `pip install json5` to install an extended JSON parser." 51*da0073e9SAndroid Build Coastguard Worker ) from ex 52*da0073e9SAndroid Build Coastguard Worker 53*da0073e9SAndroid Build Coastguard Worker settings = deep_update(current_settings, recommended_settings) 54*da0073e9SAndroid Build Coastguard Worker 55*da0073e9SAndroid Build Coastguard Worker SETTINGS.write_text( 56*da0073e9SAndroid Build Coastguard Worker json.dumps( 57*da0073e9SAndroid Build Coastguard Worker settings, 58*da0073e9SAndroid Build Coastguard Worker indent=4, 59*da0073e9SAndroid Build Coastguard Worker ) 60*da0073e9SAndroid Build Coastguard Worker + "\n", # add a trailing newline 61*da0073e9SAndroid Build Coastguard Worker encoding="utf-8", 62*da0073e9SAndroid Build Coastguard Worker ) 63*da0073e9SAndroid Build Coastguard Worker 64*da0073e9SAndroid Build Coastguard Worker 65*da0073e9SAndroid Build Coastguard Workerif __name__ == "__main__": 66*da0073e9SAndroid Build Coastguard Worker main() 67