# Copyright 2022 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Helpers for keeping stardoc documentation up-to-date. These are currently a private API in bazel-skylib. See discussion: https://github.com/bazelbuild/bazel-skylib/pull/321#issuecomment-1081166216 If you need a similar feature, you can consider using a similar rule available from a third-party: https://github.com/aspect-build/bazel-lib/blob/main/docs/docs.md """ load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("@bazel_skylib//rules:diff_test.bzl", "diff_test") def stardoc_with_diff_test( name, bzl_library_target, out_label): """Creates a stardoc target coupled with a `diff_test` for a given `bzl_library`. This is helpful for minimizing boilerplate in repos with lots of stardoc targets. Args: name: the stardoc target name bzl_library_target: the label of the `bzl_library` target to generate documentation for out_label: the label of the output MD file """ out_file = out_label.replace("//", "").replace(":", "/") # Generate MD from .bzl stardoc( name = name, out = out_file.replace(".md", "-docgen.md"), input = bzl_library_target + ".bzl", deps = [bzl_library_target], ) # Ensure that the generated MD has been updated in the local source tree diff_test( name = out_file.replace("/", "_").replace(".md", "-difftest"), failure_message = "Please run \"bazel run //docs:update\"", # Source file file1 = out_label, # Output from stardoc rule above file2 = out_file.replace(".md", "-docgen.md"), tags = ["no_windows"], ) def update_docs( name = "update", docs_folder = "docs"): """Creates a `sh_binary` target which copies over generated doc files to the local source tree. This is to be used in tandem with `stardoc_with_diff_test()` to produce a convenient workflow for generating, testing, and updating all doc files as follows: ``` bash bazel build //{docs_folder}/... && bazel test //{docs_folder}/... && bazel run //{docs_folder}:update ``` eg. ``` bash bazel build //docs/... && bazel test //docs/... && bazel run //docs:update ``` The `update_docs()` invocation must come after/below any `stardoc_with_diff_test()` invocations in the BUILD file. Args: name: the name of the `sh_binary` target docs_folder: the name of the folder containing the doc files in the local source tree """ content = ["#!/usr/bin/env bash", "cd ${BUILD_WORKSPACE_DIRECTORY}"] data = [] for r in native.existing_rules().values(): if r["kind"] == "stardoc": doc_gen = r["out"] if doc_gen.startswith(":"): doc_gen = doc_gen[1:] doc_dest = doc_gen.replace("-docgen.md", ".md") data.append(doc_gen) content.append("cp -fv bazel-bin/{0}/{1} {2}".format(docs_folder, doc_gen, doc_dest)) update_script = name + ".sh" write_file( name = "gen_" + name, out = update_script, content = content, ) native.sh_binary( name = name, srcs = [update_script], data = data, )