aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts/packages/self_extract_binary.bzl
blob: 75f19279c33fdf0311d916b14b68708d702cec15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Self-extracting binary.

Generate a binary suitable for self-extraction:

self_extract_binary(
  name = "install.sh",
  launcher = "launcher.sh",
  resources = ["path1/file1", "path2/file2"],
  flatten_ressources = ["path3/file3"],
)

will generate a file 'install.sh' with a header (launcher.sh)
and a ZIP footer with the following entries:
  path1/
  path1/file1
  path2/
  path2/file2
  file3

"""

def _self_extract_binary(ctx):
  """Implementation for the self_extract_binary rule."""
  # This is a bit complex for stripping out timestamps
  zip_artifact = ctx.new_file(ctx.label.name + ".zip")
  touch_empty_files = [
      "mkdir -p $(dirname ${tmpdir}/%s); touch ${tmpdir}/%s" % (f, f)
      for f in ctx.attr.empty_files
      ]
  cp_resources = [
      ("mkdir -p $(dirname ${tmpdir}/%s)\n" % r.short_path +
       "cp %s ${tmpdir}/%s" % (r.path, r.short_path))
      for r in ctx.files.resources
      ]
  cp_flatten_resources = [
      "cp %s ${tmpdir}/%s" % (r.path, r.basename)
      for r in ctx.files.flatten_resources
      ]
  ctx.action(
      inputs = ctx.files.resources + ctx.files.flatten_resources,
      outputs = [zip_artifact],
      command = "\n".join([
          "tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)",
          "trap \"rm -fr ${tmpdir}\" EXIT"
          ] + touch_empty_files + cp_resources + cp_flatten_resources + [
              "find ${tmpdir} -exec touch -t 198001010000.00 '{}' ';'",
              "(d=${PWD}; cd ${tmpdir}; zip -rq ${d}/%s *)" % zip_artifact.path,
              ]),
      mnemonic = "ZipBin",
  )
  ctx.action(
      inputs = [ctx.file.launcher, zip_artifact],
      outputs = [ctx.outputs.executable],
      command = "\n".join([
          "cat %s %s > %s" % (ctx.file.launcher.path,
                              zip_artifact.path,
                              ctx.outputs.executable.path),
          "zip -qA %s" % ctx.outputs.executable.path
      ]),
      mnemonic = "BuildSelfExtractable",
  )

self_extract_binary = rule(
    _self_extract_binary,
    attrs = {
        "launcher": attr.label(
            mandatory = True,
            allow_files = True,
            single_file = True,
        ),
        "empty_files": attr.string_list(default = []),
        "resources": attr.label_list(
            default = [],
            allow_files = True,
        ),
        "flatten_resources": attr.label_list(
            default = [],
            allow_files = True,
        ),
    },
    executable = True,
)