Skip to content

Commit 429574a

Browse files
committed
feat: refactor repository to add macos support
1 parent 00df5b4 commit 429574a

File tree

1 file changed

+98
-49
lines changed

1 file changed

+98
-49
lines changed

extensions.bzl

Lines changed: 98 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""Repository rule for downloading the correct version of doxygen using module extensions."""
22

3-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
3+
load("@bazel_tools//tools/build_defs/repo:cache.bzl", "get_default_canonical_id")
4+
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "get_auth")
45

5-
def _local_repository_doxygen(ctx):
6+
def _doxygen_repository(ctx):
67
"""
78
Repository rule for doxygen.
89
@@ -18,55 +19,129 @@ def _local_repository_doxygen(ctx):
1819
ctx.file("BUILD.bazel", ctx.read(ctx.attr.build))
1920
ctx.file("Doxyfile.template", ctx.read(ctx.attr.doxyfile_template))
2021

21-
# Copy the doxygen executable to the repository
22-
doxygen_content = ctx.read(ctx.attr.executable or ctx.which("doxygen"))
22+
doxygen_version = ctx.attr.version
23+
24+
# If the version is set to 0.0.0 use the installed version of doxygen from the PATH
25+
if doxygen_version == "0.0.0":
26+
if ctx.os.name.startswith("windows"):
27+
ctx.file("doxygen.exe", ctx.read(ctx.which("doxygen")), legacy_utf8 = False)
28+
else:
29+
ctx.file("doxygen", ctx.read(ctx.which("doxygen")), legacy_utf8 = False)
30+
return
31+
32+
doxygen_version_dash = doxygen_version.replace(".", "_")
33+
34+
url = "https://github.com/doxygen/doxygen/releases/download/Release_%s/doxygen-%s.%s"
35+
2336
if ctx.os.name.startswith("windows"):
24-
ctx.file("doxygen.exe", doxygen_content, legacy_utf8 = False)
37+
# For windows, download the zip file and extract the executable
38+
url = url % (doxygen_version_dash, doxygen_version, "windows.x64.bin.zip")
39+
ctx.download_and_extract(
40+
url = url,
41+
sha256 = ctx.attr.sha256,
42+
type = "zip",
43+
canonical_id = get_default_canonical_id(ctx, [url]),
44+
auth = get_auth(ctx, [url]),
45+
)
46+
2547
elif ctx.os.name.startswith("mac"):
26-
ctx.file("doxygen", doxygen_content, legacy_utf8 = False)
48+
# For mac, download the dmg file, mount it and copy the executable
49+
url = url % (doxygen_version_dash, doxygen_version, "dmg")
50+
ctx.download(
51+
url = url,
52+
sha256 = ctx.attr.sha256,
53+
canonical_id = get_default_canonical_id(ctx, [url]),
54+
auth = get_auth(ctx, [url]),
55+
)
56+
57+
# Mount the dmg file
58+
ctx.execute(["hdiutil", "attach", "-nobrowse", "-readonly", "-mouontpoint", "Doxygen", "doxygen-%s.dmg" % doxygen_version])
59+
60+
# Copy the doxygen executable to the repository
61+
ctx.file("doxygen", ctx.read("Doxygen/Applications/Doxygen.app/Contents/Resources/doxygen"), legacy_utf8 = False)
62+
63+
# Unmount the dmg file
64+
ctx.execute(["hdiutil", "detach", "Doxygen"])
65+
66+
# Delete the temporary files
67+
ctx.delete("doxygen-%s.dmg" % doxygen_version)
68+
2769
elif ctx.os.name == "linux":
28-
ctx.file("bin/doxygen", doxygen_content, legacy_utf8 = False)
70+
# For linux, download the tar.gz file and extract the executable
71+
url = url % (doxygen_version_dash, doxygen_version, "linux.bin.tar.gz")
72+
ctx.download_and_extract(
73+
url = url,
74+
sha256 = ctx.attr.sha256,
75+
type = "tar.gz",
76+
canonical_id = get_default_canonical_id(ctx, [url]),
77+
auth = get_auth(ctx, [url]),
78+
stripPrefix = "doxygen-%s" % doxygen_version,
79+
)
80+
81+
# Copy the doxygen executable to the repository
82+
ctx.file("doxygen", ctx.read("bin/doxygen"), legacy_utf8 = False)
83+
84+
# Delete other temporary files
85+
for file in ("bin", "examples", "html", "man"):
86+
ctx.delete(file)
2987
else:
3088
fail("Unsuppported OS: %s" % ctx.os.name)
3189

32-
local_repository_doxygen = repository_rule(
33-
implementation = _local_repository_doxygen,
90+
doxygen_repository = repository_rule(
91+
implementation = _doxygen_repository,
3492
doc = """
3593
Repository rule for doxygen.
3694
37-
Used to create a local repository for doxygen, containing the installed doxygen binary and all the necessary files to run the doxygen macro.
38-
In order to use this rule, you must have doxygen installed on your system and the binary (named doxygen) must available in the PATH.
39-
Keep in mind that this will break the hermeticity of your build, as it will now depend on the environment.
95+
Depending on the version, the behavior will change:
96+
- If the version is set to `0.0.0`, the repository will use the installed version of doxygen, getting the binary from the PATH.
97+
- If a version is specified, the repository will download the correct version of doxygen and make it available to the requesting module.
98+
99+
> [!Note]
100+
> The local installation version of the rules needs doxygen to be installed on your system and the binary (named doxygen) must available in the PATH.
101+
> Keep in mind that this will break the hermeticity of your build, as it will now depend on the environment.
102+
103+
You can further customize the repository by specifying the `doxygen_bzl`, `build`, and `doxyfile_template` attributes, but the default values should be enough for most use cases.
40104
41105
### Example
42106
43107
```starlark
44-
local_repository_doxygen(
108+
# Download the os specific version 1.12.0 of doxygen
109+
doxygen_repository(
45110
name = "doxygen",
111+
version = "1.12.0",
112+
sha256 = "07f1c92cbbb32816689c725539c0951f92c6371d3d7f66dfa3192cbe88dd3138",
113+
)
114+
115+
# Use the system installed version of doxygen
116+
doxygen_repository(
117+
name = "doxygen",
118+
version = "0.0.0",
46119
)
47120
```
48121
""",
49122
attrs = {
50123
"doxygen_bzl": attr.label(
51124
doc = "The starlark file containing the doxygen macro",
52125
allow_single_file = True,
53-
default = Label("@rules_doxygen//:doxygen.bzl"),
126+
default = Label("@rules_doxygen//doxygen:doxygen.bzl"),
54127
),
55128
"build": attr.label(
56129
doc = "The BUILD file of the repository",
57130
allow_single_file = True,
58-
default = Label("@rules_doxygen//:doxygen.BUILD.bazel"),
131+
default = Label("@rules_doxygen//doxygen:BUILD.bazel"),
59132
),
60133
"doxyfile_template": attr.label(
61134
doc = "The Doxyfile template to use",
62135
allow_single_file = True,
63-
default = Label("@rules_doxygen//:Doxyfile.template"),
136+
default = Label("@rules_doxygen//doxygen:Doxyfile.template"),
64137
),
65-
"executable": attr.label(
66-
executable = True,
67-
cfg = "exec",
68-
allow_single_file = True,
69-
doc = "The doxygen executable to use. Must refer to an executable file. Defaults to the doxygen executable in the PATH.",
138+
"sha256": attr.string(
139+
doc = "The sha256 hash of the doxygen archive. If not specified, an all-zero hash will be used.",
140+
default = "0" * 64,
141+
),
142+
"version": attr.string(
143+
doc = "The version of doxygen to use. If set to `0.0.0`, the doxygen executable will be assumed to be available from the PATH",
144+
mandatory = True,
70145
),
71146
},
72147
)
@@ -83,7 +158,6 @@ def _doxygen_extension_impl(ctx):
83158
if len(mod.tags.version) > 1:
84159
fail("Only one version of doxygen can be specified")
85160
doxygen_version = "1.12.0"
86-
strip_prefix = ""
87161
if ctx.os.name.startswith("windows"):
88162
doxygen_sha256 = "07f1c92cbbb32816689c725539c0951f92c6371d3d7f66dfa3192cbe88dd3138"
89163
elif ctx.os.name.startswith("mac"):
@@ -97,35 +171,10 @@ def _doxygen_extension_impl(ctx):
97171
doxygen_version = attr.version if attr.version != "" else fail("Version must be specified")
98172
doxygen_sha256 = attr.sha256 if attr.sha256 != "" else "0" * 64
99173

100-
if doxygen_version == "0.0.0":
101-
local_repository_doxygen(
102-
name = "doxygen",
103-
)
104-
return
105-
106-
doxygen_version_dash = doxygen_version.replace(".", "_")
107-
108-
url = "https://github.com/doxygen/doxygen/releases/download/Release_%s/doxygen-%s.%s"
109-
if ctx.os.name.startswith("windows"):
110-
url = url % (doxygen_version_dash, doxygen_version, "windows.x64.bin.zip")
111-
elif ctx.os.name.startswith("mac"): # TODO: support macos for hermetic build
112-
url = url % (doxygen_version_dash, doxygen_version, "dmg")
113-
fail("Unsuppported OS: %s" % ctx.os.name)
114-
elif ctx.os.name == "linux":
115-
url = url % (doxygen_version_dash, doxygen_version, "linux.bin.tar.gz")
116-
strip_prefix = "doxygen-%s" % doxygen_version
117-
else:
118-
fail("Unsuppported OS: %s" % ctx.os.name)
119-
120-
doxygen_bzl_content = ctx.read(Label("@rules_doxygen//:doxygen.bzl"))
121-
http_archive(
174+
doxygen_repository(
122175
name = "doxygen",
123-
build_file = "@rules_doxygen//:doxygen.BUILD.bazel",
124-
url = url,
125176
sha256 = doxygen_sha256,
126-
patch_cmds = ["cat > 'doxygen.bzl' <<- EOF\n%s\nEOF" % doxygen_bzl_content],
127-
patch_cmds_win = ["Set-Content -Path 'doxygen.bzl' -Value '%s'" % doxygen_bzl_content],
128-
strip_prefix = strip_prefix,
177+
version = doxygen_version,
129178
)
130179

131180
_doxygen_version = tag_class(attrs = {

0 commit comments

Comments
 (0)