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