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