github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/rules/proto_compile_gencopy.bzl (about)

     1  """proto_compile_gencopy.bzl provides the proto_compile_gencopy_run and proto_compile_gencopy_test rules.
     2  """
     3  
     4  load("//cmd/gencopy:gencopy.bzl", "gencopy_action", "gencopy_attrs", "gencopy_config")
     5  load(":providers.bzl", "ProtoCompileInfo")
     6  
     7  def _copy_file(actions, src, dst):
     8      """Copy a file to a new path destination
     9  
    10      Args:
    11        actions: the <ctx.actions> object
    12        src: the source file <File>
    13        dst: the destination path of the file
    14      Returns:
    15        <Generated File> for the copied file
    16      """
    17      actions.run_shell(
    18          mnemonic = "CopyFile",
    19          inputs = [src],
    20          outputs = [dst],
    21          command = "cp '{}' '{}'".format(src.path, dst.path),
    22          progress_message = "copying {} to {}".format(src.path, dst.path),
    23      )
    24  
    25  def _proto_compile_gencopy_impl(ctx):
    26      config = gencopy_config(ctx)
    27  
    28      runfiles = []
    29  
    30      # comprehend a mapping of relpath -> File
    31      srcfiles = {f.short_path[len(ctx.label.package):].lstrip("/"): f for f in ctx.files.srcs}
    32  
    33      for info in [dep[ProtoCompileInfo] for dep in ctx.attr.deps]:
    34          runfiles += info.outputs
    35  
    36          srcs = []  # list of string
    37          for f in info.outputs:
    38              if config.mode == "check":
    39                  # if we are in 'check' mode, the src and dst cannot be the same file, so
    40                  # make a copy of it...  but first, we need to find it in the srcs files!
    41                  found = False
    42                  for srcfilename, srcfile in srcfiles.items():
    43                      if srcfilename == f.basename:
    44                          replica = ctx.actions.declare_file(f.basename + ".actual", sibling = f)
    45                          _copy_file(ctx.actions, srcfile, replica)
    46                          runfiles.append(replica)
    47                          srcs.append(replica.short_path)
    48                          found = True
    49                          break
    50                      elif srcfilename == f.basename + ctx.attr.extension:
    51                          runfiles.append(srcfile)
    52                          srcs.append(srcfile.short_path)
    53                          found = True
    54                          break
    55                  if not found:
    56                      fail("could not find matching source file for generated file %s in %r" % (f.basename, srcfiles))
    57  
    58              else:
    59                  srcs.append(f.short_path)
    60  
    61          config.packageConfigs.append(
    62              struct(
    63                  targetLabel = str(info.label),
    64                  targetPackage = info.label.package,
    65                  targetWorkspaceRoot = info.label.workspace_root,
    66                  generatedFiles = [f.short_path for f in info.outputs],
    67                  sourceFiles = srcs,
    68              ),
    69          )
    70  
    71      config_json, script, runfiles = gencopy_action(ctx, config, runfiles)
    72  
    73      return [DefaultInfo(
    74          files = depset([config_json]),
    75          runfiles = runfiles,
    76          executable = script,
    77      )]
    78  
    79  def _proto_compile_gencopy_rule(is_test):
    80      return rule(
    81          implementation = _proto_compile_gencopy_impl,
    82          attrs = dict(
    83              gencopy_attrs,
    84              deps = attr.label_list(
    85                  doc = "The ProtoCompileInfo providers",
    86                  providers = [ProtoCompileInfo],
    87              ),
    88              srcs = attr.label_list(
    89                  doc = "The source files",
    90                  allow_files = True,
    91              ),
    92              extension = attr.string(
    93                  doc = "optional file extension to add to the copied file",
    94                  mandatory = False,
    95              ),
    96          ),
    97          executable = True,
    98          test = is_test,
    99      )
   100  
   101  proto_compile_gencopy_test = _proto_compile_gencopy_rule(True)
   102  proto_compile_gencopy_run = _proto_compile_gencopy_rule(False)