Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/scripts/update_docfx.py
3987 views
1
#!/usr/bin/env python
2
"""Update docfx_repo.bzl to the latest DocFX package on NuGet.
3
4
This script fetches the latest stable DocFX version (or a user-specified one),
5
computes the nupkg sha256, and rewrites dotnet/private/docfx_repo.bzl.
6
"""
7
8
import argparse
9
import hashlib
10
import json
11
import os
12
from pathlib import Path
13
14
import urllib3
15
from packaging.version import InvalidVersion, Version
16
17
NUGET_INDEX_URL = "https://api.nuget.org/v3-flatcontainer/docfx/index.json"
18
NUGET_NUPKG_URL = "https://api.nuget.org/v3-flatcontainer/docfx/{version}/docfx.{version}.nupkg"
19
20
http = urllib3.PoolManager()
21
22
23
def fetch_json(url):
24
r = http.request("GET", url)
25
return json.loads(r.data)
26
27
28
def choose_version(versions, allow_prerelease, explicit_version=None):
29
if explicit_version:
30
if explicit_version not in versions:
31
raise ValueError(f"Requested DocFX version {explicit_version!r} not found in NuGet index")
32
return explicit_version
33
34
parsed = []
35
for v in versions:
36
try:
37
pv = Version(v)
38
except InvalidVersion:
39
continue
40
if not allow_prerelease and pv.is_prerelease:
41
continue
42
parsed.append((pv, v))
43
44
if not parsed:
45
if allow_prerelease:
46
raise ValueError("No parseable DocFX versions found in NuGet index")
47
else:
48
raise ValueError("No stable DocFX versions found. Use --allow-prerelease to include prereleases.")
49
50
return max(parsed, key=lambda item: item[0])[1]
51
52
53
def sha256_of_url(url):
54
digest = hashlib.sha256()
55
r = http.request("GET", url, preload_content=False)
56
for chunk in r.stream(1024 * 1024):
57
digest.update(chunk)
58
r.release_conn()
59
return digest.hexdigest()
60
61
62
def render_docfx_repo(version, sha256):
63
return f'''\
64
"""Repository rule to download the docfx NuGet package."""
65
66
_BUILD = """
67
package(default_visibility = ["//visibility:public"])
68
exports_files(glob(["**/*"]))
69
filegroup(name = "docfx_dll", srcs = ["tools/net8.0/any/docfx.dll"])
70
"""
71
72
def _docfx_repo_impl(ctx):
73
ctx.download_and_extract(
74
url = "https://api.nuget.org/v3-flatcontainer/docfx/{{0}}/docfx.{{0}}.nupkg".format(ctx.attr.version),
75
sha256 = ctx.attr.sha256,
76
type = "zip",
77
)
78
ctx.file("BUILD.bazel", _BUILD)
79
80
docfx_repo = repository_rule(
81
implementation = _docfx_repo_impl,
82
attrs = {{
83
"version": attr.string(mandatory = True),
84
"sha256": attr.string(mandatory = True),
85
}},
86
)
87
88
def _docfx_extension_impl(module_ctx):
89
docfx_repo(
90
name = "docfx",
91
version = "{version}",
92
sha256 = "{sha256}",
93
)
94
return module_ctx.extension_metadata(reproducible = True)
95
96
docfx_extension = module_extension(implementation = _docfx_extension_impl)
97
'''
98
99
100
def main():
101
parser = argparse.ArgumentParser()
102
parser.add_argument(
103
"--version",
104
help="Use this DocFX version instead of the latest stable.",
105
)
106
parser.add_argument(
107
"--allow-prerelease",
108
action="store_true",
109
help="Allow prerelease versions when selecting latest.",
110
)
111
parser.add_argument(
112
"--output",
113
default="dotnet/private/docfx_repo.bzl",
114
help="Output file path (default: dotnet/private/docfx_repo.bzl)",
115
)
116
args = parser.parse_args()
117
118
index = fetch_json(NUGET_INDEX_URL)
119
versions = index.get("versions", [])
120
if not versions:
121
raise ValueError("NuGet index returned no versions for DocFX")
122
123
version = choose_version(versions, args.allow_prerelease, args.version)
124
nupkg_url = NUGET_NUPKG_URL.format(version=version)
125
sha256 = sha256_of_url(nupkg_url)
126
127
output_path = Path(args.output)
128
if not output_path.is_absolute():
129
workspace_dir = os.environ.get("BUILD_WORKSPACE_DIRECTORY")
130
if workspace_dir:
131
output_path = Path(workspace_dir) / output_path
132
output_path.write_text(render_docfx_repo(version, sha256))
133
134
print(f"Updated {output_path} to DocFX {version}")
135
136
137
if __name__ == "__main__":
138
main()
139
140