| # Copyright (C) 2024 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import json |
| import os |
| import logging |
| import tempfile |
| |
| # To generate rust-project.json from bazel, run |
| # bazel run @rules_rust//tools/rust_analyzer:gen_rust_project --norepository_disable_download @gbl//efi:main |
| # However, this yields incorrect source path. |
| # Your source file |
| # /usr/local/google/home/zhangkelvin/uefi-gbl-mainline/bootable/libbootloader/gbl/efi/src/main.rs |
| # would turn into |
| # /usr/local/google/home/uefi-gbl-mainline/out/bazel/output_user_root/e14d642d361d598c63507c64a56ecbc7/execroot/_main/external/gbl/efi/src/main.rs |
| # and this confuses the rust-analyzer. This script will resolve the right |
| # source path for you by checking if any of the parent path is a symlink, |
| # and resolve all symlinks to final destination. |
| |
| |
| def traverse(obj: dict): |
| if isinstance(obj, dict): |
| for (key, val) in obj.items(): |
| if key == "root_module" or key == "CARGO_MANIFEST_DIR": |
| obj[key] = os.path.realpath(val) |
| continue |
| elif key == "include_dirs" or key == "exclude_dirs": |
| obj[key] = [os.path.realpath(d) for d in val] |
| continue |
| elif key == "cfg" and isinstance(val, list): |
| obj[key] = [o for o in val if o != "test"] |
| continue |
| traverse(val) |
| elif isinstance(obj, list): |
| for item in obj: |
| traverse(item) |
| |
| |
| def main(argv): |
| logging.basicConfig(level=logging.INFO) |
| rust_project_json_path = "rust-project.json" |
| if len(argv) == 2: |
| rust_project_json_path = argv[1] |
| rust_project_json_path = os.path.realpath(rust_project_json_path) |
| project_root_path = os.path.dirname(rust_project_json_path) |
| logging.info("Using %s as project root path", project_root_path) |
| with open(rust_project_json_path, "r") as fp: |
| data = json.load(fp) |
| traverse(data) |
| |
| with tempfile.NamedTemporaryFile("w+") as fp: |
| json.dump(data, fp.file, indent=True) |
| os.rename(fp.name, rust_project_json_path) |
| # create the tempfile again so deleting it works after exiting this scope |
| with open(fp.name, "w"): |
| pass |
| |
| |
| if __name__ == "__main__": |
| import sys |
| |
| main(sys.argv) |