blob: ea23abc74a08c01210ecc34c40b9412adabc582a [file] [log] [blame]
Philipp Schrader37fdbb62021-12-18 00:30:37 -08001"""Provides helper functions for mirroring Go repositories."""
2
Philipp Schraderd96d4cb2022-02-06 15:37:29 -08003import json
4import subprocess
Philipp Schrader37fdbb62021-12-18 00:30:37 -08005from typing import List, Dict
Philipp Schraderd96d4cb2022-02-06 15:37:29 -08006import unittest.mock
7
8from bazel_tools.tools.python.runfiles import runfiles
Philipp Schrader37fdbb62021-12-18 00:30:37 -08009
10
11def read_file(filepath: str) -> str:
12 """Reads an entire file by returning its contents as a string."""
13 with open(filepath, "r") as file:
14 return file.read()
15
16def parse_go_repositories(filepath: str) -> List[Dict[str, str]]:
17 """Parses the top-level go_deps.bzl file.
18
19 This function can parse both the original version of the file generated by
20 gazelle as well as the tweaked version generated by
21 tweak_gazelle_go_deps.py. The two versions are identical other than what function they call.
22 """
23 global_functions = {
24 "load": unittest.mock.MagicMock(),
25 # The gazelle generated version uses go_repository().
26 "go_repository": unittest.mock.MagicMock(),
27 # The tweak_gazelle_go_deps.py generated version uses
28 # maybe_override_go_dep().
29 "maybe_override_go_dep": unittest.mock.MagicMock()
30 }
31 compiled_code = compile(read_file(filepath), filepath, "exec")
32 eval(compiled_code, global_functions)
33
34 # Extract the repositories defined in the go_dependencies() function from
35 # go_deps.bzl.
36 global_functions["go_dependencies"]()
37
38 repositories = []
39 for repo_kind in ("go_repository", "maybe_override_go_dep"):
40 for repo in global_functions[repo_kind].mock_calls:
41 _, _, kwargs = repo
42 repositories.append(kwargs)
43
44 return repositories
45
Philipp Schraderd96d4cb2022-02-06 15:37:29 -080046
47def parse_go_mirror_info(filepath: str) -> Dict[str, Dict[str, str]]:
48 """Parses the tools/go/go_mirrors.bzl file and returns the GO_MIRROR_INFO dictionary."""
49 global_data = {}
50 compiled_code = compile(read_file(filepath), filepath, "exec")
51 eval(compiled_code, global_data)
52
53 return global_data["GO_MIRROR_INFO"]
54
55
56def write_go_mirror_info(filepath: str, mirror_info: Dict[str, Dict[str, str]]):
57 """Saves the specified mirror_info as GO_MIRROR_INFO into tools/go/go_mirrors.bzl."""
58 with open(filepath, "w") as file:
59 file.write("# This file is auto-generated. Do not edit.\n")
60 file.write("GO_MIRROR_INFO = ")
61 # Format as JSON first. It's parsable as Starlark.
62 json.dump(mirror_info, file, indent=4, sort_keys=True)
63 file.write("\n")
64
65 # Properly format the file now so that the linter doesn't complain.
66 r = runfiles.Create()
67 subprocess.run(
68 [
69 r.Rlocation("com_github_bazelbuild_buildtools/buildifier/buildifier_/buildifier"),
70 filepath,
71 ],
72 check=True)