| #!/usr/bin/env fuchsia-vendored-python | |
| # Copyright 2026 The Fuchsia Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Formats an input list of paths as extraPaths for pyrightconfig.json""" | |
| import json | |
| import os | |
| import re | |
| from pathlib import Path | |
| def create_pyright_base_config(build_dir: Path, fuchsia_dir: Path) -> set[Path]: | |
| """Create a base config for pyright-based IDE integrations. | |
| Args: | |
| build_dir: Fuchsia build directory. | |
| fuchsia_dir: Fuchsia source directory. | |
| Returns: | |
| A set of Path values for the input files read by this function. | |
| """ | |
| extra_python_paths_file = build_dir / "extra_python_dirs.json" | |
| source_paths_file = fuchsia_dir / "build/python/static_extra_paths.json5" | |
| output_file = build_dir / "pyrightconfig.base.json" | |
| build_directory_path = os.path.relpath(build_dir, fuchsia_dir) | |
| if not os.path.isfile(extra_python_paths_file): | |
| raise FileNotFoundError( | |
| f"Python paths file '{extra_python_paths_file}' does not exist." | |
| ) | |
| if not os.path.isfile(source_paths_file): | |
| raise FileNotFoundError( | |
| f"Input file '{source_paths_file}' does not exist." | |
| ) | |
| paths: set[str] = set() | |
| with open(extra_python_paths_file, "r") as input_file: | |
| input_data: object = json.load(input_file) | |
| if not isinstance(input_data, list): | |
| raise TypeError( | |
| f"Input file {extra_python_paths_file} must contain a list." | |
| ) | |
| # FIDL paths are relative to the build directory, so we need to prepend that path. | |
| paths.update( | |
| [ | |
| os.path.normpath(os.path.join(build_directory_path, path)) | |
| for path in input_data | |
| ], | |
| ) | |
| with open(source_paths_file, "r") as input_file: | |
| # Strip comments and trailing commas in containers. Pyright handles them fine, | |
| # but standard Python json does not like them. | |
| lines = [ | |
| l for l in input_file.readlines() if not l.lstrip().startswith("//") | |
| ] | |
| content = re.sub(r",(\s*[}\]])", r"\1", "".join(lines)) | |
| source_input: object = json.loads(content) | |
| if not isinstance(source_input, list): | |
| raise TypeError( | |
| f"Input file {source_paths_file} must contain a list." | |
| ) | |
| paths.update(source_input) | |
| with open(output_file, "w") as out_file: | |
| output = {"extraPaths": sorted(paths)} | |
| json.dump(output, out_file, indent=2) | |
| return {source_paths_file} |