feat: collect transitive sources
diff --git a/doxygen/doxygen.bzl b/doxygen/doxygen.bzl index 02e0828..d8d81f8 100644 --- a/doxygen/doxygen.bzl +++ b/doxygen/doxygen.bzl
@@ -2,7 +2,7 @@ def _expand_make_variables(string, ctx): """Replace make variables in a string with their values. - + Args: string: The string to expand. ctx: The context object. @@ -12,6 +12,41 @@ string = string.replace("$(%s)" % variable, value) return string + +TransitiveSourcesInfo = provider(fields = ["srcs"]) + +def _collect_files_aspect_impl(target, ctx): + """Collect transitive source files from dependencies. + + Args: + target: aspect target + ctx: aspect context + + Returns: + TransitiveSourcesInfo with a depset of transitive sources + """ + direct_files = [] + srcs = ctx.rule.attr.srcs if hasattr(ctx.rule.attr, "srcs") else [] + hdrs = ctx.rule.attr.hdrs if hasattr(ctx.rule.attr, "hdrs") else [] + for src in srcs + hdrs: + if hasattr(src, "files"): + direct_files.extend(src.files.to_list()) + + # Collect transitive files from dependencies + srcs = [] + for dep in ctx.rule.attr.deps: + if TransitiveSourcesInfo in dep: + srcs.append(dep[TransitiveSourcesInfo].srcs) + + return [TransitiveSourcesInfo( + srcs = depset(direct=direct_files, transitive=srcs), + )] + +collect_files_aspect = aspect( + implementation = _collect_files_aspect_impl, + attr_aspects = ["deps"], # recursively apply on deps +) + def _doxygen_impl(ctx): doxyfile = ctx.actions.declare_file("Doxyfile") @@ -27,7 +62,8 @@ if len(outs) == 0: fail("At least one output folder must be specified") - input_dirs = {(file.dirname or "."): None for file in ctx.files.srcs} + deps = depset(transitive = [dep[TransitiveSourcesInfo].srcs for dep in ctx.attr.deps]).to_list() + input_dirs = {(file.dirname or "."): None for file in ctx.files.srcs + deps} ctx.actions.expand_template( template = ctx.file.doxyfile_template, output = doxyfile, @@ -40,7 +76,7 @@ ) ctx.actions.run( - inputs = ctx.files.srcs + [doxyfile], + inputs = ctx.files.srcs + deps + [doxyfile], outputs = outs, arguments = [doxyfile.path] + ctx.attr.doxygen_extra_args, progress_message = "Running doxygen", @@ -84,13 +120,14 @@ implementation = _doxygen_impl, attrs = { "srcs": attr.label_list(allow_files = True, doc = "The source files to generate documentation for. Can include header files, source files, and any other file Doxygen can parse."), + "deps": attr.label_list(aspects = [collect_files_aspect]), "configurations": attr.string_list(doc = "Additional configuration parameters to append to the Doxyfile. For example, to set the project name, use `PROJECT_NAME = example`."), "outs": attr.string_list(default = ["html"], allow_empty = False, doc = """The output folders to keep. If only the html outputs is of interest, the default value will do. Otherwise, a list of folders to keep is expected (e.g. `["html", "latex"]`)."""), "doxyfile_template": attr.label( allow_single_file = True, default = Label(":Doxyfile.template"), - doc = """The template file to use to generate the Doxyfile. You can provide your own or use the default one. -The following substitutions are available: + doc = """The template file to use to generate the Doxyfile. You can provide your own or use the default one. +The following substitutions are available: - `# {{INPUT}}`: Subpackage directory in the sandbox. - `# {{DOT_PATH}}`: Indicate to doxygen the location of the `dot_executable` - `# {{ADDITIONAL PARAMETERS}}`: Additional parameters given in the `configurations` attribute. @@ -1113,7 +1150,7 @@ _add_generic_configuration(configurations, "MSCFILE_DIRS", mscfile_dirs) if doxyfile_template: - kwargs["doxyfile_template"] = doxyfile_template + kwargs["doxyfile_template"] = doxyfile_template _doxygen( name = name,