diff --git a/docs/advanced_stardoc_usage.md b/docs/advanced_stardoc_usage.md index bad4167..8526a94 100644 --- a/docs/advanced_stardoc_usage.md +++ b/docs/advanced_stardoc_usage.md @@ -34,6 +34,21 @@ def my_function(foo, bar): Markdown formatting constructs are handled appropriately by Stardoc's default output format ("markdown_tables"), even as part of a table. +### Documenting global symbols + +With Bazel 9 or newer, global values without a built-in documentation mechanism, +such as strings, lists, dictionaries, and structs, can be documented with `#:` +comments: + +```starlark +#: The default timeout used by this module. +DEFAULT_TIMEOUT = 60 +``` + +The extracted documentation includes the symbol's name, documentation, and +Starlark type. Bazel does not currently include the symbol's value in the +Stardoc output proto. + ## Custom Output diff --git a/docs/stardoc_rule.md b/docs/stardoc_rule.md index 5a4ac42..2c23a91 100644 --- a/docs/stardoc_rule.md +++ b/docs/stardoc_rule.md @@ -11,11 +11,11 @@ load("@stardoc//stardoc:stardoc.bzl", "stardoc") stardoc(*, name, input, out, deps, format, symbol_names, renderer, aspect_template, func_template, macro_template, header_template, table_of_contents_template, provider_template, rule_template, - repository_rule_template, module_extension_template, footer_template, render_main_repo_name, - stamp, **kwargs) + repository_rule_template, module_extension_template, starlark_other_symbol_template, + footer_template, render_main_repo_name, stamp, **kwargs) -Generates documentation for exported starlark rule definitions in a target starlark file. +Generates documentation for exported symbols in a target Starlark file. **PARAMETERS** @@ -27,7 +27,7 @@ Generates documentation for exported starlark rule definitions in a target starl | out | The file to which documentation will be output (mandatory). | none | | deps | A list of bzl_library dependencies which the input depends on. | `[]` | | format | The format of the output file. Valid values: 'markdown' or 'proto'. | `"markdown"` | -| symbol_names | A list of symbol names to generate documentation for. These should correspond to the names of rule definitions in the input file. If this list is empty, then documentation for all exported rule definitions will be generated. | `[]` | +| symbol_names | A list of exported symbol names to generate documentation for. If this list is empty, documentation for all exported symbols will be generated. | `[]` | | renderer | The location of the renderer tool. | `Label("@stardoc//stardoc:renderer")` | | aspect_template | The input file template for generating documentation of aspects | `Label("@stardoc//stardoc:templates/markdown_tables/aspect.vm")` | | func_template | The input file template for generating documentation of functions, including legacy macros. | `Label("@stardoc//stardoc:templates/markdown_tables/func.vm")` | @@ -38,6 +38,7 @@ Generates documentation for exported starlark rule definitions in a target starl | rule_template | The input file template for generating documentation of rules. | `Label("@stardoc//stardoc:templates/markdown_tables/rule.vm")` | | repository_rule_template | The input file template for generating documentation of repository rules. | `Label("@stardoc//stardoc:templates/markdown_tables/repository_rule.vm")` | | module_extension_template | The input file template for generating documentation of module extensions. | `Label("@stardoc//stardoc:templates/markdown_tables/module_extension.vm")` | +| starlark_other_symbol_template | The input file template for generating documentation of Starlark global symbols, such as constants, which use `#:` doc comments. | `Label("@stardoc//stardoc:templates/markdown_tables/starlark_other_symbol.vm")` | | footer_template | The input file template for generating the footer of the output documentation. Optional. | `None` | | render_main_repo_name | Render labels in the main repository with a repo component (either the module name or workspace name). | `True` | | stamp | Whether to provide stamping information to templates, where it can be accessed via `$util.formatBuildTimestamp()` and`$stamping`. Example:
Built on `$util.formatBuildTimestamp($stamping.volatile.BUILD_TIMESTAMP, "UTC", "yyyy-MM-dd HH:mm")`
Possible values: Stamped targets are not rebuilt unless their dependencies change. | `-1` | diff --git a/src/main/java/com/google/devtools/build/stardoc/renderer/RendererMain.java b/src/main/java/com/google/devtools/build/stardoc/renderer/RendererMain.java index 9981c80..dd8aea6 100644 --- a/src/main/java/com/google/devtools/build/stardoc/renderer/RendererMain.java +++ b/src/main/java/com/google/devtools/build/stardoc/renderer/RendererMain.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.RepositoryRuleInfo; import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.RuleInfo; import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.StarlarkFunctionInfo; +import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.StarlarkOtherSymbolInfo; import com.google.devtools.build.stardoc.rendering.MarkdownRenderer; import com.google.devtools.build.stardoc.rendering.MarkdownRenderer.Renderer; import com.google.devtools.build.stardoc.rendering.Stamping; @@ -98,6 +99,7 @@ public void println() { rendererOptions.aspectTemplateFilePath, rendererOptions.repositoryRuleTemplateFilePath, rendererOptions.moduleExtensionTemplateFilePath, + rendererOptions.starlarkOtherSymbolTemplateFilePath, !moduleInfo.getFile().isEmpty() ? Optional.of(moduleInfo.getFile()) : Optional.empty(), @@ -154,6 +156,12 @@ public void println() { .sorted(comparing(ModuleExtensionInfo::getExtensionName)) .collect(toImmutableList()); + // Other documented Starlark symbols are printed sorted by their qualified name. + ImmutableList sortedStarlarkOtherSymbolInfos = + ImmutableList.sortedCopyOf( + comparing(StarlarkOtherSymbolInfo::getName), + moduleInfo.getStarlarkOtherSymbolInfoList()); + printWriter.println(renderer.renderMarkdownHeader(moduleInfo)); if (rendererOptions.tableOfContentsTemplateFilePath != null) { printWriter.println( @@ -164,7 +172,8 @@ public void println() { sortedStarlarkFunctions, sortedAspectInfos, sortedRepositoryRuleInfos, - sortedModuleExtensionInfos)); + sortedModuleExtensionInfos, + sortedStarlarkOtherSymbolInfos)); } print(printWriter, renderer::render, sortedRuleInfos); print(printWriter, renderer::render, sortedProviderInfos); @@ -173,6 +182,7 @@ public void println() { print(printWriter, renderer::render, sortedAspectInfos); print(printWriter, renderer::render, sortedRepositoryRuleInfos); print(printWriter, renderer::render, sortedModuleExtensionInfos); + print(printWriter, renderer::render, sortedStarlarkOtherSymbolInfos); if (rendererOptions.footerTemplateFilePath != null) { printWriter.println(renderer.renderMarkdownFooter(moduleInfo)); } diff --git a/src/main/java/com/google/devtools/build/stardoc/renderer/RendererOptions.java b/src/main/java/com/google/devtools/build/stardoc/renderer/RendererOptions.java index ad778b0..55029f4 100644 --- a/src/main/java/com/google/devtools/build/stardoc/renderer/RendererOptions.java +++ b/src/main/java/com/google/devtools/build/stardoc/renderer/RendererOptions.java @@ -86,6 +86,12 @@ class RendererOptions { description = "The template for the documentation of a module extension") String moduleExtensionTemplateFilePath; + @Parameter( + names = "--starlark_other_symbol_template", + required = true, + description = "The template for the documentation of a Starlark global symbol") + String starlarkOtherSymbolTemplateFilePath; + @Parameter(names = "--footer_template", description = "The template for the footer string") String footerTemplateFilePath; diff --git a/src/main/java/com/google/devtools/build/stardoc/rendering/MarkdownRenderer.java b/src/main/java/com/google/devtools/build/stardoc/rendering/MarkdownRenderer.java index 703e6a0..ee37bff 100644 --- a/src/main/java/com/google/devtools/build/stardoc/rendering/MarkdownRenderer.java +++ b/src/main/java/com/google/devtools/build/stardoc/rendering/MarkdownRenderer.java @@ -30,6 +30,7 @@ import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.RepositoryRuleInfo; import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.RuleInfo; import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.StarlarkFunctionInfo; +import com.google.devtools.build.lib.starlarkdocextract.StardocOutputProtos.StarlarkOtherSymbolInfo; import com.google.escapevelocity.EvaluationException; import com.google.escapevelocity.ParseException; import com.google.escapevelocity.Template; @@ -61,6 +62,7 @@ public interface Renderer { private final String aspectTemplateFilename; private final String repositoryRuleTemplateFilename; private final String moduleExtensionTemplateFilename; + private final String starlarkOtherSymbolTemplateFilename; private final Optional entrypointBzlFile; private final String footerTemplateFilename; private final Stamping stamping; @@ -75,6 +77,7 @@ public MarkdownRenderer( String aspectTemplate, String repositoryRuleTemplate, String moduleExtensionTemplate, + String starlarkOtherSymbolTemplate, Optional entrypointBzlFile, String footerTemplate, Stamping stamping) { @@ -87,6 +90,7 @@ public MarkdownRenderer( this.aspectTemplateFilename = aspectTemplate; this.repositoryRuleTemplateFilename = repositoryRuleTemplate; this.moduleExtensionTemplateFilename = moduleExtensionTemplate; + this.starlarkOtherSymbolTemplateFilename = starlarkOtherSymbolTemplate; this.entrypointBzlFile = entrypointBzlFile; this.footerTemplateFilename = footerTemplate; this.stamping = stamping; @@ -124,7 +128,8 @@ public String renderTableOfContents( List starlarkFunctions, List aspectInfos, List repositoryRuleInfos, - List moduleExtensionInfos) + List moduleExtensionInfos, + List starlarkOtherSymbolInfos) throws IOException { ImmutableMap vars = @@ -136,7 +141,8 @@ public String renderTableOfContents( "functionInfos", starlarkFunctions, "aspectInfos", aspectInfos, "repositoryRuleInfos", repositoryRuleInfos, - "moduleExtensionInfos", moduleExtensionInfos); + "moduleExtensionInfos", moduleExtensionInfos, + "starlarkOtherSymbolInfos", starlarkOtherSymbolInfos); Reader reader = readerFromPath(tableOfContentsTemplateFilename); try { return Template.parseFrom(reader).evaluate(vars); @@ -348,6 +354,22 @@ public String render(ModuleExtensionInfo moduleExtensionInfo) throws IOException } } + /** Returns a markdown rendering of a documented Starlark global symbol. */ + public String render(StarlarkOtherSymbolInfo starlarkOtherSymbolInfo) throws IOException { + ImmutableMap vars = + ImmutableMap.of( + "util", + new MarkdownUtil(entrypointBzlFile), + "symbolInfo", + starlarkOtherSymbolInfo); + Reader reader = readerFromPath(starlarkOtherSymbolTemplateFilename); + try { + return Template.parseFrom(reader).evaluate(vars); + } catch (ParseException | EvaluationException e) { + throw new IOException(e); + } + } + /** Returns a markdown header string that should appear at the end of Stardoc's output. */ public String renderMarkdownFooter(ModuleInfo moduleInfo) throws IOException { ImmutableMap vars = diff --git a/stardoc/html_tables_stardoc.bzl b/stardoc/html_tables_stardoc.bzl index e2487a5..7bedfdb 100644 --- a/stardoc/html_tables_stardoc.bzl +++ b/stardoc/html_tables_stardoc.bzl @@ -35,5 +35,6 @@ def html_tables_stardoc(name, **kwargs): rule_template = Label("//stardoc:templates/html_tables/rule.vm"), repository_rule_template = Label("//stardoc:templates/html_tables/repository_rule.vm"), module_extension_template = Label("//stardoc:templates/html_tables/module_extension.vm"), + starlark_other_symbol_template = Label("//stardoc:templates/html_tables/starlark_other_symbol.vm"), **kwargs ) diff --git a/stardoc/private/stardoc.bzl b/stardoc/private/stardoc.bzl index 0c80b0f..3bc5a9e 100644 --- a/stardoc/private/stardoc.bzl +++ b/stardoc/private/stardoc.bzl @@ -42,6 +42,7 @@ def _renderer_action_run(ctx, out_file, proto_file): renderer_args.add("--rule_template=" + str(ctx.file.rule_template.path)) renderer_args.add("--repository_rule_template=" + str(ctx.file.repository_rule_template.path)) renderer_args.add("--module_extension_template=" + str(ctx.file.module_extension_template.path)) + renderer_args.add("--starlark_other_symbol_template=" + str(ctx.file.starlark_other_symbol_template.path)) if ctx.file.footer_template: renderer_args.add("--footer_template=" + str(ctx.file.footer_template.path)) if stamp_enabled: @@ -58,6 +59,7 @@ def _renderer_action_run(ctx, out_file, proto_file): ctx.file.rule_template, ctx.file.repository_rule_template, ctx.file.module_extension_template, + ctx.file.starlark_other_symbol_template, ] if ctx.attr.table_of_contents_template: inputs.append(ctx.file.table_of_contents_template) @@ -138,6 +140,11 @@ _common_renderer_attrs = { allow_single_file = [".vm"], mandatory = True, ), + "starlark_other_symbol_template": attr.label( + doc = "The input file template for generating documentation of Starlark global symbols.", + allow_single_file = [".vm"], + mandatory = True, + ), "footer_template": attr.label( doc = "The input file template for generating the footer of the output documentation. Optional.", allow_single_file = [".vm"], @@ -190,7 +197,7 @@ _stardoc_markdown_renderer_attrs = { stardoc_markdown_renderer = rule( _stardoc_markdown_renderer_impl, doc = """ -Generates markdown documentation for starlark rule definitions from the corresponding binary proto. +Generates Markdown documentation for Starlark symbols from the corresponding binary proto. """, attrs = _stardoc_markdown_renderer_attrs, ) diff --git a/stardoc/stardoc.bzl b/stardoc/stardoc.bzl index 67dbb6d..c0ce6e7 100644 --- a/stardoc/stardoc.bzl +++ b/stardoc/stardoc.bzl @@ -35,11 +35,12 @@ def stardoc( rule_template = Label("//stardoc:templates/markdown_tables/rule.vm"), repository_rule_template = Label("//stardoc:templates/markdown_tables/repository_rule.vm"), module_extension_template = Label("//stardoc:templates/markdown_tables/module_extension.vm"), + starlark_other_symbol_template = Label("//stardoc:templates/markdown_tables/starlark_other_symbol.vm"), footer_template = None, render_main_repo_name = True, stamp = -1, **kwargs): - """Generates documentation for exported starlark rule definitions in a target starlark file. + """Generates documentation for exported symbols in a target Starlark file. Args: name: The name of the stardoc target. @@ -47,9 +48,8 @@ def stardoc( out: The file to which documentation will be output (mandatory). deps: A list of bzl_library dependencies which the input depends on. format: The format of the output file. Valid values: 'markdown' or 'proto'. - symbol_names: A list of symbol names to generate documentation for. These should correspond to the names of rule - definitions in the input file. If this list is empty, then documentation for all exported rule definitions will - be generated. + symbol_names: A list of exported symbol names to generate documentation for. If this list is + empty, documentation for all exported symbols will be generated. renderer: The location of the renderer tool. aspect_template: The input file template for generating documentation of aspects header_template: The input file template for the header of the output documentation. @@ -62,6 +62,8 @@ def stardoc( rule_template: The input file template for generating documentation of rules. repository_rule_template: The input file template for generating documentation of repository rules. module_extension_template: The input file template for generating documentation of module extensions. + starlark_other_symbol_template: The input file template for generating documentation of + Starlark global symbols, such as constants, which use `#:` doc comments. footer_template: The input file template for generating the footer of the output documentation. Optional. render_main_repo_name: Render labels in the main repository with a repo component (either the module name or workspace name). @@ -132,6 +134,7 @@ def stardoc( rule_template = rule_template, repository_rule_template = repository_rule_template, module_extension_template = module_extension_template, + starlark_other_symbol_template = starlark_other_symbol_template, macro_template = macro_template, footer_template = footer_template, stamp = stamp, diff --git a/stardoc/templates/html_tables/starlark_other_symbol.vm b/stardoc/templates/html_tables/starlark_other_symbol.vm new file mode 100644 index 0000000..64df0b8 --- /dev/null +++ b/stardoc/templates/html_tables/starlark_other_symbol.vm @@ -0,0 +1,9 @@ + + +#[[##]]# ${symbolInfo.name} (`${symbolInfo.typeName}`) + +
+${util.loadStatement($symbolInfo.name)}
+
+ +${util.htmlEscape($symbolInfo.doc)} diff --git a/stardoc/templates/markdown_tables/starlark_other_symbol.vm b/stardoc/templates/markdown_tables/starlark_other_symbol.vm new file mode 100644 index 0000000..e6f9a4e --- /dev/null +++ b/stardoc/templates/markdown_tables/starlark_other_symbol.vm @@ -0,0 +1,9 @@ + + +#[[##]]# ${symbolInfo.name} (`${symbolInfo.typeName}`) + +
+${util.loadStatement($symbolInfo.name)}
+
+ +${symbolInfo.doc} diff --git a/stardoc/templates/markdown_tables/table_of_contents.vm b/stardoc/templates/markdown_tables/table_of_contents.vm index c5dfd8b..43f85a3 100644 --- a/stardoc/templates/markdown_tables/table_of_contents.vm +++ b/stardoc/templates/markdown_tables/table_of_contents.vm @@ -55,3 +55,11 @@ #end #end +#if (!$starlarkOtherSymbolInfos.isEmpty()) +#[[##]]# Globals + +#foreach ($symbolInfo in $starlarkOtherSymbolInfos) +- [$symbolInfo.name](#$symbolInfo.name) +#end + +#end diff --git a/test/BUILD b/test/BUILD index 847d810..b4e796d 100644 --- a/test/BUILD +++ b/test/BUILD @@ -54,6 +54,27 @@ stardoc_test( symbol_names = ["my_rule"], ) +stardoc_test( + name = "starlark_other_symbols_test", + golden_file = "testdata/starlark_other_symbols_test/golden.md", + input_file = "testdata/starlark_other_symbols_test/input.bzl", + tags = [ + "bazel_9", + "manual", + ], +) + +stardoc_test( + name = "starlark_other_symbols_html_tables_test", + golden_file = "testdata/starlark_other_symbols_test/html_tables_golden.md", + input_file = "testdata/starlark_other_symbols_test/input.bzl", + tags = [ + "bazel_9", + "manual", + ], + test = "html_tables", +) + stardoc_test( name = "repo_rules_test", golden_file = "testdata/repo_rules_test/golden.md", diff --git a/test/testdata/starlark_other_symbols_test/golden.md b/test/testdata/starlark_other_symbols_test/golden.md new file mode 100644 index 0000000..a7faa1a --- /dev/null +++ b/test/testdata/starlark_other_symbols_test/golden.md @@ -0,0 +1,38 @@ + + +A golden test for documented Starlark global symbols. + + + +## A_STRING (`string`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "A_STRING")
+
+ +A documented string constant. + + + + +## STRUCT_CONSTANT (`struct`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "STRUCT_CONSTANT")
+
+ +A documented struct constant. + + + + +## Z_LIST (`list`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "Z_LIST")
+
+ +The first line of documentation for a list. +The second line of documentation for a list. + + diff --git a/test/testdata/starlark_other_symbols_test/html_tables_golden.md b/test/testdata/starlark_other_symbols_test/html_tables_golden.md new file mode 100644 index 0000000..a7faa1a --- /dev/null +++ b/test/testdata/starlark_other_symbols_test/html_tables_golden.md @@ -0,0 +1,38 @@ + + +A golden test for documented Starlark global symbols. + + + +## A_STRING (`string`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "A_STRING")
+
+ +A documented string constant. + + + + +## STRUCT_CONSTANT (`struct`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "STRUCT_CONSTANT")
+
+ +A documented struct constant. + + + + +## Z_LIST (`list`) + +
+load("@stardoc//test:testdata/starlark_other_symbols_test/input.bzl", "Z_LIST")
+
+ +The first line of documentation for a list. +The second line of documentation for a list. + + diff --git a/test/testdata/starlark_other_symbols_test/input.bzl b/test/testdata/starlark_other_symbols_test/input.bzl new file mode 100644 index 0000000..528cc16 --- /dev/null +++ b/test/testdata/starlark_other_symbols_test/input.bzl @@ -0,0 +1,17 @@ +"""A golden test for documented Starlark global symbols.""" + +#: A documented string constant. +A_STRING = "a string" + +#: A documented struct constant. +STRUCT_CONSTANT = struct(foo = 1) + +#: The first line of documentation for a list. +#: The second line of documentation for a list. +Z_LIST = ["one", "two"] + +#: Private symbols are not included in generated documentation. +_PRIVATE_CONSTANT = 42 + +# Undocumented constant +UNDOCUMENTED_CONSTANT = _PRIVATE_CONSTANT == 42 diff --git a/test/testdata/table_of_contents_test/golden.md b/test/testdata/table_of_contents_test/golden.md index a999b39..d4d48ec 100644 --- a/test/testdata/table_of_contents_test/golden.md +++ b/test/testdata/table_of_contents_test/golden.md @@ -34,6 +34,10 @@ Test rules / providers / etc for the table of contents generation test. - [my_ext](#my_ext) +## Globals + +- [MY_GLOBAL](#MY_GLOBAL) + @@ -305,3 +309,14 @@ Artifact tag | group | Group name | String | optional | `"my_group"` | + + +## MY_GLOBAL (`string`) + +
+load("@stardoc//test:testdata/table_of_contents_test/input.bzl", "MY_GLOBAL")
+
+ +A documented global string. + + diff --git a/test/testdata/table_of_contents_test/input.bzl b/test/testdata/table_of_contents_test/input.bzl index f88f55c..25b421a 100644 --- a/test/testdata/table_of_contents_test/input.bzl +++ b/test/testdata/table_of_contents_test/input.bzl @@ -27,3 +27,6 @@ my_repo = _my_repo my_ext = _my_ext basic_macro = _basic_macro + +#: A documented global string. +MY_GLOBAL = "my global"