blob: 220e0bb3525bfeacaac312a003c807197cc42302 [file] [log] [blame]
# 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)