• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2024 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import json
16import os
17import logging
18import tempfile
19import shutil
20
21# To generate rust-project.json from bazel, run
22# bazel run @rules_rust//tools/rust_analyzer:gen_rust_project --norepository_disable_download @gbl//efi:main
23# However, this yields incorrect source path.
24# Your source file
25# /usr/local/google/home/zhangkelvin/uefi-gbl-mainline/bootable/libbootloader/gbl/efi/src/main.rs
26# would turn into
27# /usr/local/google/home/uefi-gbl-mainline/out/bazel/output_user_root/e14d642d361d598c63507c64a56ecbc7/execroot/_main/external/gbl/efi/src/main.rs
28# and this confuses the rust-analyzer. This script will resolve the right
29# source path for you by checking if any of the parent path is a symlink,
30# and resolve all symlinks to final destination.
31
32
33def traverse(obj: dict):
34  if isinstance(obj, dict):
35    for (key, val) in obj.items():
36      if key == "root_module" or key == "CARGO_MANIFEST_DIR":
37        obj[key] = os.path.realpath(val)
38        continue
39      elif key == "include_dirs" or key == "exclude_dirs":
40        obj[key] = [os.path.realpath(d) for d in val]
41        continue
42      elif key == "cfg" and isinstance(val, list):
43        obj[key] = [o for o in val if o != "test"]
44        continue
45      traverse(val)
46  elif isinstance(obj, list):
47    for item in obj:
48      traverse(item)
49
50
51def main(argv):
52  logging.basicConfig(level=logging.INFO)
53  rust_project_json_path = "rust-project.json"
54  if len(argv) == 2:
55    rust_project_json_path = argv[1]
56  rust_project_json_path = os.path.realpath(rust_project_json_path)
57  project_root_path = os.path.dirname(rust_project_json_path)
58  logging.info("Using %s as project root path", project_root_path)
59  with open(rust_project_json_path, "r") as fp:
60    data = json.load(fp)
61    traverse(data)
62
63  with tempfile.NamedTemporaryFile("w+", delete=False) as fp:
64    json.dump(data, fp.file, indent=True)
65    tmp_path = fp.name
66  shutil.move(tmp_path, rust_project_json_path)
67
68
69if __name__ == "__main__":
70  import sys
71
72  main(sys.argv)
73