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