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 )