kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/web/site/site_docs.bzl (about)

     1  load("//kythe/docs:asciidoc.bzl", "AsciidocInfo")
     2  load("@bazel_skylib//lib:paths.bzl", "paths")
     3  load("@bazel_skylib//lib:shell.bzl", "shell")
     4  
     5  _AsciidocHeaderInfo = provider(
     6      fields = {"header": "File with the asciidoc header."},
     7  )
     8  
     9  _SiteDocsInfo = provider()
    10  
    11  def _header_impl(target, ctx):
    12      src = ctx.rule.file.src
    13      header = ctx.actions.declare_file(paths.replace_extension(src.path, "head." + src.extension))
    14      ctx.actions.run(
    15          inputs = [src],
    16          outputs = [header],
    17          tools = [ctx.executable._docheader],
    18          executable = ctx.executable._docheader,
    19          arguments = [src.path, header.path],
    20          mnemonic = "JekyllHeader",
    21      )
    22  
    23      return [
    24          _AsciidocHeaderInfo(header = header),
    25      ]
    26  
    27  _header_aspect = aspect(
    28      implementation = _header_impl,
    29      attrs = {
    30          "_docheader": attr.label(
    31              default = Label("//kythe/web/site:doc_header"),
    32              executable = True,
    33              cfg = "exec",
    34          ),
    35      },
    36  )
    37  
    38  def _impl(ctx):
    39      outdir = ctx.actions.declare_directory(ctx.label.name)
    40      commands = []
    41      inputs = []
    42      for src in ctx.attr.srcs:
    43          header = src[_AsciidocHeaderInfo].header
    44          html = src[AsciidocInfo].primary_output_path
    45          resources = src[AsciidocInfo].resource_dir
    46          inputs += [resources, header]
    47          commands += [
    48              # Copy only the files from the resource dir, omitting the html file itself
    49              # or we will get subsequent permissions problems.
    50              "find {resource_dir} -mindepth 1 -maxdepth 1 -depth -not -path {html} -exec cp -L -r {{}} {outdir} \\;".format(
    51                  resource_dir = shell.quote(resources.path),
    52                  outdir = shell.quote(outdir.path),
    53                  html = shell.quote(paths.join(resources.path, html)),
    54              ),
    55              "cat {header} {html} > {output}".format(
    56                  header = shell.quote(header.path),
    57                  html = shell.quote(paths.join(resources.path, html)),
    58                  output = shell.quote(paths.join(outdir.path, html)),
    59              ),
    60          ]
    61      for dep in ctx.attr.deps:
    62          files = dep.files.to_list()
    63          inputs += files
    64          commands += [
    65              "cp -L -r {file} {outdir}".format(
    66                  file = shell.quote(file.path),
    67                  outdir = shell.quote(outdir.path),
    68              )
    69              for file in files
    70          ]
    71  
    72      commands.append("pushd {outdir}".format(outdir = shell.quote(outdir.path)))
    73      for src, dest in ctx.attr.rename_files.items():
    74          commands.append("mv {src} {dest}".format(
    75              src = shell.quote(src),
    76              dest = shell.quote(dest),
    77          ))
    78      commands.append("popd")
    79  
    80      ctx.actions.run_shell(
    81          mnemonic = "BuildDocs",
    82          inputs = inputs,
    83          outputs = [outdir],
    84          command = "\n".join([
    85              "set -e",
    86              "mkdir -p {outdir}".format(outdir = shell.quote(outdir.path)),
    87          ] + commands),
    88      )
    89  
    90      return [
    91          # Only include the root directory in our declared outputs.
    92          # This ensure that downstream rules don't see files listed twice if the expand tree artifacts.
    93          DefaultInfo(files = depset([outdir])),
    94          _SiteDocsInfo(),
    95      ]
    96  
    97  site_docs = rule(
    98      implementation = _impl,
    99      attrs = {
   100          "srcs": attr.label_list(
   101              aspects = [_header_aspect],
   102              providers = [AsciidocInfo],
   103          ),
   104          "deps": attr.label_list(
   105              providers = [_SiteDocsInfo],
   106          ),
   107          "rename_files": attr.string_dict(),
   108      },
   109  )
   110  
   111  def _package_path(file):
   112      pkgroot = paths.join(file.root.path, file.owner.package)
   113      return paths.relativize(file.path, pkgroot)
   114  
   115  def _jekyll_impl(ctx):
   116      input_root = ctx.label.name + ".staging.d"
   117      symlinks = []
   118      for src in ctx.files.srcs:
   119          declare_output = ctx.actions.declare_directory if src.is_directory else ctx.actions.declare_file
   120          symlink = declare_output(paths.join(input_root, _package_path(src)))
   121          ctx.actions.symlink(output = symlink, target_file = src)
   122          symlinks.append(symlink)
   123      input_dir = paths.join(symlinks[0].root.path, symlinks[0].owner.package, input_root)
   124  
   125      outdir = ctx.outputs.out
   126      if not outdir:
   127          outdir = ctx.actions.declare_directory("_site")
   128  
   129      # Dummy command for now.
   130      args = ctx.actions.args()
   131      args.add("build")
   132      args.add("-s", input_dir)
   133      args.add("-d", outdir.path)
   134      ctx.actions.run(
   135          outputs = [outdir],
   136          inputs = symlinks,
   137          arguments = [args],
   138          executable = ctx.executable._jekyll,
   139          # TODO(shahms): We don't currently have a Ruby toolchain in the RBE environment.
   140          execution_requirements = {"local": ""},
   141          mnemonic = "JekyllBuild",
   142      )
   143  
   144      return [
   145          DefaultInfo(files = depset([outdir])),
   146      ]
   147  
   148  jekyll_build = rule(
   149      implementation = _jekyll_impl,
   150      attrs = {
   151          "out": attr.output(),
   152          "srcs": attr.label_list(
   153              allow_files = True,
   154          ),
   155          "_jekyll": attr.label(
   156              default = "@website_bundle//:bin/jekyll",
   157              executable = True,
   158              cfg = "exec",
   159              allow_files = True,
   160          ),
   161      },
   162  )