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 = """
3593Repository 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\n EOF" % 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