tools

various tools I have been using throughout the years
Log | Files | Refs | README | LICENSE

local-deploy.bzl (3369B)


      1 """
      2 Rule for local *nix deployment of a binary build artifact.
      3 
      4 This is useful for local development but is not intended for production deployments.
      5 """
      6 
      7 def _local_deploy_impl(ctx):
      8     target = ctx.attr.target
      9     copy_runfiles = ctx.attr.copy_runfiles
     10 
     11     # We use a set to avoid duplicates if multiple targets provide the same file
     12     files_map = {}
     13     transitive_runfiles = []
     14 
     15     for t in ctx.attr.srcs:
     16         if DefaultInfo in t:
     17             info = t[DefaultInfo]
     18             transitive_runfiles.append(info.default_runfiles)
     19             
     20             # If it's an executable, we prefer that.
     21             if info.files_to_run.executable:
     22                  exe = info.files_to_run.executable
     23                  files_map[exe.short_path] = exe
     24             else:
     25                  # Otherwise take all files
     26                  for f in info.files.to_list():
     27                      files_map[f.short_path] = f
     28     
     29     # Sort for determinism
     30     sorted_paths = sorted(files_map.keys())
     31     
     32     final_files = []
     33     
     34     script_content = [
     35         "#!/bin/bash",
     36         "set -e",
     37         "TARGET_DIR=%s" % target,
     38         "sudo mkdir -p \"$TARGET_DIR\"",
     39         "",
     40         "# Locate the runfiles directory of this deploy script",
     41         "if [ -n \"$RUNFILES_DIR\" ]; then",
     42         "    RUNFILES_SOURCE=\"$RUNFILES_DIR\"",
     43         "elif [ -d \"${0}.runfiles\" ]; then",
     44         "    RUNFILES_SOURCE=\"${0}.runfiles\"",
     45         "else",
     46         "    RUNFILES_SOURCE=\"\"",
     47         "fi",
     48         ""
     49     ]
     50     
     51     for path in sorted_paths:
     52         # If "foo.sh" and "foo" exist, skip "foo.sh".
     53         is_shadowed = False
     54         for ext in [".sh", ".py"]:
     55             if path.endswith(ext):
     56                 wrapper = path[:-len(ext)]
     57                 if wrapper in files_map:
     58                     is_shadowed = True
     59                     break
     60 
     61         if is_shadowed:
     62             continue
     63 
     64         f = files_map[path]
     65         final_files.append(f)
     66 
     67         # Add copy command
     68         script_content.extend([
     69             "SRC=\"%s\"" % f.short_path,
     70             "REAL=$(readlink -f \"$SRC\")",
     71             "echo \"Copying $SRC to $TARGET_DIR\"",
     72             "sudo cp \"$REAL\" \"$TARGET_DIR/$(basename \"$SRC\")\"",
     73         ])
     74 
     75         # Copy runfiles if enabled
     76         if copy_runfiles:
     77             script_content.extend([
     78                 "if [ -n \"$RUNFILES_SOURCE\" ]; then",
     79                 "    DEST_RUNFILES=\"$TARGET_DIR/$(basename \"$SRC\").runfiles\"",
     80                 "    echo \"Copying runfiles to $DEST_RUNFILES\"",
     81                 "    sudo rm -rf \"$DEST_RUNFILES\"",
     82                 "    sudo cp -r \"$RUNFILES_SOURCE\" \"$DEST_RUNFILES\"",
     83                 "fi",
     84                 "",
     85             ])
     86 
     87     ctx.actions.write(
     88         output = ctx.outputs.executable,
     89         is_executable = True,
     90         content = "\n".join(script_content)
     91     )
     92     
     93     runfiles = ctx.runfiles(files = final_files)
     94     for r in transitive_runfiles:
     95         runfiles = runfiles.merge(r)
     96 
     97     return DefaultInfo(
     98         executable = ctx.outputs.executable,
     99         runfiles = runfiles,
    100     )
    101 
    102 local_deploy = rule(
    103     executable = True,
    104     implementation = _local_deploy_impl,
    105     attrs = {
    106         "srcs": attr.label_list(allow_files = True),
    107         "target": attr.string(default = "~/.local/share/tools"),
    108         "copy_runfiles": attr.bool(default = False),
    109     },
    110 )