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)