Remove pkg_deb from @bazel_tools.
https://github.com/bazelbuild/bazel/issues/8857
Fixes #11217 (https://github.com/bazelbuild/bazel/issues/11217)
RELNOTES:
pkg_deb is no longer part of @bazel_tools//build_defs/pkg:pkg.bzl.
Use https://github.com/bazelbuild/rules_pkg/tree/main/pkg instead
PiperOrigin-RevId: 360464481
diff --git a/tools/build_defs/pkg/BUILD b/tools/build_defs/pkg/BUILD
index 4c2c9b9..bdd8347 100644
--- a/tools/build_defs/pkg/BUILD
+++ b/tools/build_defs/pkg/BUILD
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-load("//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar")
+load("//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
load("//tools/config:common_settings.bzl", "bool_flag")
load("//tools/python:private/defs.bzl", "py_binary", "py_library", "py_test")
@@ -22,7 +22,6 @@
visibility = ["//site:__pkg__"],
)
-# Used by pkg_deb
py_library(
name = "archive",
srcs = ["archive.py"],
@@ -72,21 +71,6 @@
],
)
-py_binary(
- name = "make_deb",
- srcs = ["make_deb.py"],
- deprecation = "The internal version of make_deb is deprecated. Please " +
- "use the replacement for pkg_deb from " +
- "https://github.com/bazelbuild/rules_pkg/blob/master/pkg.",
- python_version = "PY3",
- srcs_version = "PY2AND3",
- visibility = ["//visibility:public"],
- deps = [
- ":archive",
- "//third_party/py/abseil",
- ],
-)
-
# tests
genrule(
@@ -98,29 +82,6 @@
cmd = "for i in $(OUTS); do echo 1 >$$i; done",
)
-pkg_deb(
- name = "test-deb",
- built_using = "some_test_data (0.1.2)",
- conffiles = [
- "/etc/nsswitch.conf",
- "/etc/other",
- ],
- config = ":testdata/config",
- data = ":test-tar-gz.tar.gz",
- depends = [
- "dep1",
- "dep2",
- ],
- description = "toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é",
- distribution = "trusty",
- maintainer = "soméone@somewhere.com",
- make_deb = ":make_deb",
- package = "titi",
- templates = ":testdata/templates",
- urgency = "low",
- version = "test",
-)
-
[pkg_tar(
name = "test-tar-%s" % ext[1:],
srcs = [
@@ -237,7 +198,6 @@
],
data = [
"testenv.sh",
- ":test-deb.deb",
":test-tar-.tar",
":test-tar-bz2.tar.bz2",
":test-tar-empty_dirs.tar",
diff --git a/tools/build_defs/pkg/README.md b/tools/build_defs/pkg/README.md
index b898da7..9888d02 100644
--- a/tools/build_defs/pkg/README.md
+++ b/tools/build_defs/pkg/README.md
@@ -4,15 +4,11 @@
These rules have been extracted from the Bazel sources and are now available at
[bazelbuild/rules_pkg](https://github.com/bazelbuild/rules_pkg/releases)
- [(docs)](https://github.com/bazelbuild/rules_pkg/tree/master/pkg).
+ [(docs)](https://github.com/bazelbuild/rules_pkg/tree/main/pkg).
Issues and PRs against the built-in versions of these rules will no longer be
addressed. This page will exist for reference until the code is removed from
-Bazel. You can test the removal of these rules with Bazel at version >= 0.28.0.
-
-```
-bazel build --//tools/build_defs/pkg:incompatible_no_build_defs_pkg target...
-```
+Bazel.
For more information, follow [issue 8857](https://github.com/bazelbuild/bazel/issues/8857)
@@ -22,22 +18,23 @@
<h2>Rules</h2>
<ul>
<li><a href="#pkg_tar">pkg_tar</a></li>
- <li><a href="#pkg_deb">pkg_deb</a></li>
</ul>
</div>
## Overview
-These build rules are used for building various packaging such as tarball
-and debian package.
+`pkg_tar()` is available for building a .tar file without depending
+on anything besides Bazel. Since this feature is deprecated and will
+eventually be removed from Bazel, you should migrate to `@rules_pkg`.
<a name="basic-example"></a>
## Basic Example
-This example is a simplification of the debian packaging of Bazel:
+This example is a simplification of building Bazel and creating a distribution
+tarball.
```python
-load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar", "pkg_deb")
+load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
pkg_tar(
name = "bazel-bin",
@@ -56,49 +53,25 @@
)
pkg_tar(
- name = "debian-data",
+ name = "bazel-all",
extension = "tar.gz",
deps = [
":bazel-bin",
":bazel-tools",
],
)
-
-pkg_deb(
- name = "bazel-debian",
- architecture = "amd64",
- built_using = "unzip (6.0.1)",
- data = ":debian-data",
- depends = [
- "zlib1g-dev",
- "unzip",
- ],
- description_file = "debian/description",
- homepage = "http://bazel.build",
- maintainer = "The Bazel Authors <bazel-dev@googlegroups.com>",
- package = "bazel",
- version = "0.1.1",
-)
```
-Here, the Debian package is built from three `pkg_tar` targets:
+Here, a package is built from three `pkg_tar` targets:
- `bazel-bin` creates a tarball with the main binary (mode `0755`) in
`/usr/bin`,
- `bazel-tools` create a tarball with the base workspace (mode `0644`) to
`/usr/share/bazel/tools` ; the `modes` attribute let us specifies executable
files,
- - `debian-data` creates a gzip-compressed tarball that merge the three previous
+ - `bazel-all` creates a gzip-compressed tarball that merge the two previous
tarballs.
-`debian-data` is then used for the data content of the debian archive created by
-`pkg_deb`.
-
-<a name="future"></a>
-## Future work
-
- - Support more format, especially `pkg_zip`.
- - Maybe a bit more integration with the `docker_build` rule.
<a name="pkg_tar"></a>
## pkg_tar
@@ -335,191 +308,3 @@
</tr>
</tbody>
</table>
-
-<a name="pkg_deb"></a>
-### pkg_deb
-
-```python
-pkg_deb(name, data, package, architecture, maintainer, preinst, postinst, prerm, postrm, version, version_file, description, description_file, built_using, built_using_file, priority, section, homepage, depends, suggests, enhances, conflicts, predepends, recommends)
-```
-
-Create a debian package. See <a
-href="http://www.debian.org/doc/debian-policy/ch-controlfields.html">http://www.debian.org/doc/debian-policy/ch-controlfields.html</a>
-for more details on this.
-
-<table class="table table-condensed table-bordered table-params">
- <colgroup>
- <col class="col-param" />
- <col class="param-description" />
- </colgroup>
- <thead>
- <tr>
- <th colspan="2">Attributes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>name</code></td>
- <td>
- <code>Name, required</code>
- <p>A unique name for this rule.</p>
- </td>
- </tr>
- <tr>
- <td><code>data</code></td>
- <td>
- <code>File, required</code>
- <p>
- A tar file that contains the data for the debian package (basically
- the list of files that will be installed by this package).
- </p>
- </td>
- </tr>
- <tr>
- <td><code>package</code></td>
- <td>
- <code>String, required</code>
- <p>The name of the package.</p>
- </td>
- </tr>
- <tr>
- <td><code>architecture</code></td>
- <td>
- <code>String, default to 'all'</code>
- <p>The architecture that this package target.</p>
- <p>
- See <a href="http://www.debian.org/ports/">http://www.debian.org/ports/</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>maintainer</code></td>
- <td>
- <code>String, required</code>
- <p>The maintainer of the package.</p>
- </td>
- </tr>
- <tr>
- <td><code>preinst</code>, <code>postinst</code>, <code>prerm</code> and <code>postrm</code></td>
- <td>
- <code>Files, optional</code>
- <p>
- Respectively, the pre-install, post-install, pre-remove and
- post-remove scripts for the package.
- </p>
- <p>
- See <a href="http://www.debian.org/doc/debian-policy/ch-maintainerscripts.html">http://www.debian.org/doc/debian-policy/ch-maintainerscripts.html</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>config</code></td>
- <td>
- <code>File, optional</code>
- <p>
- config file used for debconf integration.
- </p>
- <p>
- See <a href="https://www.debian.org/doc/debian-policy/ch-binary.html#prompting-in-maintainer-scripts">https://www.debian.org/doc/debian-policy/ch-binary.html#prompting-in-maintainer-scripts</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>templates</code></td>
- <td>
- <code>File, optional</code>
- <p>
- templates file used for debconf integration.
- </p>
- <p>
- See <a href="https://www.debian.org/doc/debian-policy/ch-binary.html#prompting-in-maintainer-scripts">https://www.debian.org/doc/debian-policy/ch-binary.html#prompting-in-maintainer-scripts</a>.
- </p>
- </td>
- </tr>
-
- <tr>
- <td><code>conffiles</code>, <code>conffiles_file</code></td>
- <td>
- <code>String list or File, optional</code>
- <p>
- The list of conffiles or a file containing one conffile per
- line. Each item is an absolute path on the target system
- where the deb is installed.
- </p>
- <p>
- See <a href="https://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html#s-conffile">https://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html#s-conffile</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>version</code>, <code>version_file</code></td>
- <td>
- <code>String or File, required</code>
- <p>
- The package version provided either inline (with <code>version</code>)
- or from a file (with <code>version_file</code>).
- </p>
- </td>
- </tr>
- <tr>
- <td><code>description</code>, <code>description_file</code></td>
- <td>
- <code>String or File, required</code>
- <p>
- The package description provided either inline (with <code>description</code>)
- or from a file (with <code>description_file</code>).
- </p>
- </td>
- </tr>
- <tr>
- <td><code>built_using</code>, <code>built_using_file</code></td>
- <td>
- <code>String or File</code>
- <p>
- The tool that were used to build this package provided either inline
- (with <code>built_using</code>) or from a file (with <code>built_using_file</code>).
- </p>
- </td>
- </tr>
- <tr>
- <td><code>priority</code></td>
- <td>
- <code>String, default to 'optional'</code>
- <p>The priority of the package.</p>
- <p>
- See <a href="http://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities">http://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>section</code></td>
- <td>
- <code>String, default to 'contrib/devel'</code>
- <p>The section of the package.</p>
- <p>
- See <a href="http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections">http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>homepage</code></td>
- <td>
- <code>String, optional</code>
- <p>The homepage of the project.</p>
- </td>
- </tr>
- <tr>
- <td>
- <code>depends</code>, <code>suggests</code>, <code>enhances</code>,
- <code>conflicts</code>, <code>predepends</code> and <code>recommends</code>.
- </td>
- <td>
- <code>String list, optional</code>
- <p>The list of dependencies in the project.</p>
- <p>
- See <a href="http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps">http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps</a>.
- </p>
- </td>
- </tr>
- </tbody>
-</table>
diff --git a/tools/build_defs/pkg/archive.py b/tools/build_defs/pkg/archive.py
index b497a21..d786624 100644
--- a/tools/build_defs/pkg/archive.py
+++ b/tools/build_defs/pkg/archive.py
@@ -30,81 +30,6 @@
PORTABLE_MTIME = 946684800 # 2000-01-01 00:00:00.000 UTC
-class SimpleArFile(object):
- """A simple AR file reader.
-
- This enable to read AR file (System V variant) as described
- in https://en.wikipedia.org/wiki/Ar_(Unix).
-
- The standard usage of this class is:
-
- with SimpleArFile(filename) as ar:
- nextFile = ar.next()
- while nextFile:
- print(nextFile.filename)
- nextFile = ar.next()
-
- Upon error, this class will raise a ArError exception.
- """
-
- # TODO(dmarting): We should use a standard library instead but python 2.7
- # does not have AR reading library.
-
- class ArError(Exception):
- pass
-
- class SimpleArFileEntry(object):
- """Represent one entry in a AR archive.
-
- Attributes:
- filename: the filename of the entry, as described in the archive.
- timestamp: the timestamp of the file entry.
- owner_id, group_id: numeric id of the user and group owning the file.
- mode: unix permission mode of the file
- size: size of the file
- data: the content of the file.
- """
-
- def __init__(self, f):
- self.filename = f.read(16).decode('utf-8').strip()
- if self.filename.endswith('/'): # SysV variant
- self.filename = self.filename[:-1]
- self.timestamp = int(f.read(12).strip())
- self.owner_id = int(f.read(6).strip())
- self.group_id = int(f.read(6).strip())
- self.mode = int(f.read(8).strip(), 8)
- self.size = int(f.read(10).strip())
- pad = f.read(2)
- if pad != b'\x60\x0a':
- raise SimpleArFile.ArError('Invalid AR file header')
- self.data = f.read(self.size)
-
- MAGIC_STRING = b'!<arch>\n'
-
- def __init__(self, filename):
- self.filename = filename
-
- def __enter__(self):
- self.f = open(self.filename, 'rb')
- if self.f.read(len(self.MAGIC_STRING)) != self.MAGIC_STRING:
- raise self.ArError('Not a ar file: ' + six.ensure_str(self.filename))
- return self
-
- def __exit__(self, t, v, traceback):
- self.f.close()
-
- def next(self):
- """Read the next file. Returns None when reaching the end of file."""
- # AR sections are two bit aligned using new lines.
- if self.f.tell() % 2 != 0:
- self.f.read(1)
- # An AR sections is at least 60 bytes. Some file might contains garbage
- # bytes at the end of the archive, ignore them.
- if self.f.tell() > os.fstat(self.f.fileno()).st_size - 60:
- return None
- return self.SimpleArFileEntry(self.f)
-
-
class TarFileWriter(object):
"""A wrapper to write tar files."""
diff --git a/tools/build_defs/pkg/archive_test.py b/tools/build_defs/pkg/archive_test.py
index f5696c6..9ab79c4 100644
--- a/tools/build_defs/pkg/archive_test.py
+++ b/tools/build_defs/pkg/archive_test.py
@@ -30,74 +30,6 @@
from tools.build_defs.pkg import testenv
-class SimpleArFileTest(unittest.TestCase):
- """Testing for SimpleArFile class."""
-
- def assertArFileContent(self, arfile, content):
- """Assert that arfile contains exactly the entry described by `content`.
-
- Args:
- arfile: the path to the AR file to test.
- content: an array describing the expected content of the AR file.
- Each entry in that list should be a dictionary where each field
- is a field to test in the corresponding SimpleArFileEntry. For
- testing the presence of a file "x", then the entry could simply
- be `{"filename": "x"}`, the missing field will be ignored.
- """
- with archive.SimpleArFile(arfile) as f:
- current = f.next()
- i = 0
- while current:
- error_msg = "Extraneous file at end of archive %s: %s" % (
- arfile,
- current.filename
- )
- self.assertTrue(i < len(content), error_msg)
- for k, v in content[i].items():
- value = getattr(current, k)
- error_msg = " ".join([
- "Value `%s` for key `%s` of file" % (value, k),
- "%s in archive %s does" % (current.filename, arfile),
- "not match expected value `%s`" % v
- ])
- self.assertEqual(value, v, error_msg)
- current = f.next()
- i += 1
- if i < len(content):
- self.fail("Missing file %s in archive %s" % (content[i], arfile))
-
- def testEmptyArFile(self):
- self.assertArFileContent(os.path.join(testenv.TESTDATA_PATH, "empty.ar"),
- [])
-
- def assertSimpleFileContent(self, names):
- datafile = os.path.join(testenv.TESTDATA_PATH, "_".join(names) + ".ar")
- content = [{
- "filename": n,
- "size": len(six.ensure_binary(n, "utf-8")),
- "data": six.ensure_binary(n, "utf-8")
- } for n in names]
- self.assertArFileContent(datafile, content)
-
- def testAFile(self):
- self.assertSimpleFileContent(["a"])
-
- def testBFile(self):
- self.assertSimpleFileContent(["b"])
-
- def testABFile(self):
- self.assertSimpleFileContent(["ab"])
-
- def testA_BFile(self):
- self.assertSimpleFileContent(["a", "b"])
-
- def testA_ABFile(self):
- self.assertSimpleFileContent(["a", "ab"])
-
- def testA_B_ABFile(self):
- self.assertSimpleFileContent(["a", "b", "ab"])
-
-
class TarFileWriterTest(unittest.TestCase):
"""Testing for TarFileWriter class."""
diff --git a/tools/build_defs/pkg/build_test.sh b/tools/build_defs/pkg/build_test.sh
index 10a709c..0be65f5 100755
--- a/tools/build_defs/pkg/build_test.sh
+++ b/tools/build_defs/pkg/build_test.sh
@@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Unit tests for pkg_deb and pkg_tar
+# Unit tests for pkg_tar
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
source ${DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; }
@@ -55,63 +55,6 @@
tar tvf "${test_data}" | fgrep "00 $file" | cut -d " " -f 1
}
-function get_deb_listing() {
- local input=$1
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb -c "${test_data}" | sed -e 's/^.*:00 //'
-}
-
-function get_deb_description() {
- local input=$1
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb -I "${test_data}"
-}
-
-function get_deb_permission() {
- local input=$1
- local file=$2
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb -c "${test_data}" | fgrep "00 $file" | cut -d " " -f 1
-}
-
-function get_deb_ctl_file() {
- local input=$1
- local file=$2
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb -I "${test_data}" "${file}"
-}
-
-function get_deb_ctl_listing() {
- local input=$1
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb --ctrl-tarfile "${test_data}" | tar tf - | sort
-}
-
-function get_deb_ctl_file() {
- local input=$1
- local ctl_file=$2
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb --info "${test_data}" "${ctl_file}"
-}
-
-function get_deb_ctl_permission() {
- local input=$1
- local file=$2
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb --ctrl-tarfile "${test_data}" | tar tvf - | egrep " $file\$" | cut -d " " -f 1
-}
-
-function dpkg_deb_supports_ctrl_tarfile() {
- local input=$1
- local test_data="${TEST_DATA_DIR}/${input}"
- dpkg-deb --ctrl-tarfile "${test_data}" > /dev/null 2> /dev/null
-}
-
-function get_changes() {
- local input=$1
- cat "${TEST_DATA_DIR}/${input}"
-}
-
function assert_content() {
local listing="./
./etc/
@@ -177,55 +120,5 @@
"$(get_tar_verbose_listing test-tar-mtime.tar)"
}
-function test_deb() {
- if ! (which dpkg-deb); then
- echo "Unable to run test for debian, no dpkg-deb!" >&2
- return 0
- fi
- local listing="./
-./etc/
-./etc/nsswitch.conf
-./usr/
-./usr/titi
-./usr/bin/
-./usr/bin/java -> /path/to/bin/java"
- check_eq "$listing" "$(get_deb_listing test-deb.deb)"
- check_eq "-rwxr-xr-x" "$(get_deb_permission test-deb.deb ./usr/titi)"
- check_eq "-rw-r--r--" "$(get_deb_permission test-deb.deb ./etc/nsswitch.conf)"
- get_deb_description test-deb.deb >$TEST_log
- expect_log "Description: toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é"
- expect_log "Package: titi"
- expect_log "soméone@somewhere.com"
- expect_log "Depends: dep1, dep2"
- expect_log "Built-Using: some_test_data"
-
- get_changes titi_test_all.changes >$TEST_log
- expect_log "Urgency: low"
- expect_log "Distribution: trusty"
-
- get_deb_ctl_file test-deb.deb templates >$TEST_log
- expect_log "Template: titi/test"
- expect_log "Type: string"
-
- get_deb_ctl_file test-deb.deb config >$TEST_log
- expect_log "# test config file"
-
- if ! dpkg_deb_supports_ctrl_tarfile test-deb.deb ; then
- echo "Unable to test deb control files listing, too old dpkg-deb!" >&2
- return 0
- fi
- local ctrl_listing="conffiles
-config
-control
-templates"
- check_eq "$ctrl_listing" "$(get_deb_ctl_listing test-deb.deb)"
- check_eq "-rw-r--r--" "$(get_deb_ctl_permission test-deb.deb conffiles)"
- check_eq "-rwxr-xr-x" "$(get_deb_ctl_permission test-deb.deb config)"
- check_eq "-rw-r--r--" "$(get_deb_ctl_permission test-deb.deb control)"
- check_eq "-rwxr-xr-x" "$(get_deb_ctl_permission test-deb.deb templates)"
- local conffiles="/etc/nsswitch.conf
-/etc/other"
- check_eq "$conffiles" "$(get_deb_ctl_file test-deb.deb conffiles)"
-}
run_suite "build_test"
diff --git a/tools/build_defs/pkg/make_deb.py b/tools/build_defs/pkg/make_deb.py
deleted file mode 100644
index dc10699..0000000
--- a/tools/build_defs/pkg/make_deb.py
+++ /dev/null
@@ -1,374 +0,0 @@
-# Lint as: python2, python3
-# 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.
-"""A simple cross-platform helper to create a debian package."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import gzip
-import hashlib
-from io import BytesIO
-import os
-import os.path
-import tarfile
-import textwrap
-import time
-
-# Do not edit this line. Copybara replaces it with PY2 migration helper.
-from absl import app
-from absl import flags
-import six
-
-# list of debian fields : (name, mandatory, wrap[, default])
-# see http://www.debian.org/doc/debian-policy/ch-controlfields.html
-DEBIAN_FIELDS = [
- ('Package', True, False),
- ('Version', True, False),
- ('Section', False, False, 'contrib/devel'),
- ('Priority', False, False, 'optional'),
- ('Architecture', False, False, 'all'),
- ('Depends', False, True, []),
- ('Recommends', False, True, []),
- ('Suggests', False, True, []),
- ('Enhances', False, True, []),
- ('Conflicts', False, True, []),
- ('Pre-Depends', False, True, []),
- ('Installed-Size', False, False),
- ('Maintainer', True, False),
- ('Description', True, True),
- ('Homepage', False, False),
- ('Built-Using', False, False, None),
- ('Distribution', False, False, 'unstable'),
- ('Urgency', False, False, 'medium'),
-]
-
-flags.DEFINE_string('output', None, 'The output file, mandatory')
-flags.mark_flag_as_required('output')
-
-flags.DEFINE_string('changes', None, 'The changes output file, mandatory.')
-flags.mark_flag_as_required('changes')
-
-flags.DEFINE_string('data', None, 'Path to the data tarball, mandatory')
-flags.mark_flag_as_required('data')
-
-flags.DEFINE_string('preinst', None,
- 'The preinst script (prefix with @ to provide a path).')
-flags.DEFINE_string('postinst', None,
- 'The postinst script (prefix with @ to provide a path).')
-flags.DEFINE_string('prerm', None,
- 'The prerm script (prefix with @ to provide a path).')
-flags.DEFINE_string('postrm', None,
- 'The postrm script (prefix with @ to provide a path).')
-flags.DEFINE_string('config', None,
- 'The config script (prefix with @ to provide a path).')
-flags.DEFINE_string('templates', None,
- 'The templates file (prefix with @ to provide a path).')
-
-# size of chunks for copying package content to final .deb file
-# This is a wild guess, but I am not convinced of the value of doing much work
-# to tune it.
-_COPY_CHUNK_SIZE = 1024 * 32
-
-# see
-# https://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html#s-conffile
-flags.DEFINE_multi_string(
- 'conffile', None,
- 'List of conffiles (prefix item with @ to provide a path)')
-
-
-def Makeflags():
- """Creates a flag for each of the control file fields."""
- for field in DEBIAN_FIELDS:
- fieldname = field[0].replace('-', '_').lower()
- msg = 'The value for the %s content header entry.' % field[0]
- if len(field) > 3:
- if isinstance(field[3], list):
- flags.DEFINE_multi_string(fieldname, field[3], msg)
- else:
- flags.DEFINE_string(fieldname, field[3], msg)
- else:
- flags.DEFINE_string(fieldname, None, msg)
- if field[1]:
- flags.mark_flag_as_required(fieldname)
-
-
-def ConvertToFileLike(content, content_len, converter):
- if content_len < 0:
- content_len = len(content)
- content = converter(content)
- return content_len, content
-
-
-def AddArFileEntry(fileobj, filename,
- content='', content_len=-1, timestamp=0,
- owner_id=0, group_id=0, mode=0o644):
- """Add a AR file entry to fileobj."""
- # If we got the content as a string, turn it into a file like thing.
- if isinstance(content, (str, bytes)):
- content_len, content = ConvertToFileLike(content, content_len, BytesIO)
- inputs = [
- (six.ensure_str(filename) + '/').ljust(16), # filename (SysV)
- str(timestamp).ljust(12), # timestamp
- str(owner_id).ljust(6), # owner id
- str(group_id).ljust(6), # group id
- str(oct(mode)).replace('0o', '0').ljust(8), # mode
- str(content_len).ljust(10), # size
- '\x60\x0a', # end of file entry
- ]
- for i in inputs:
- fileobj.write(i.encode('ascii'))
- size = 0
- while True:
- data = content.read(_COPY_CHUNK_SIZE)
- if not data:
- break
- size += len(data)
- fileobj.write(data)
- if size % 2 != 0:
- fileobj.write(b'\n') # 2-byte alignment padding
-
-
-def MakeDebianControlField(name, value, wrap=False):
- """Add a field to a debian control file."""
- result = name + ': '
- if isinstance(value, str):
- value = six.ensure_str(value, 'utf-8')
- if isinstance(value, list):
- value = ', '.join(six.ensure_str(v) for v in value)
- if wrap:
- result += ' '.join(six.ensure_str(value).split('\n'))
- result = textwrap.fill(result,
- break_on_hyphens=False,
- break_long_words=False)
- else:
- result += value
- return result.replace('\n', '\n ') + '\n'
-
-
-def CreateDebControl(extrafiles=None, **kwargs):
- """Create the control.tar.gz file."""
- # create the control file
- controlfile = ''
- for values in DEBIAN_FIELDS:
- fieldname = values[0]
- key = fieldname[0].lower() + fieldname[1:].replace('-', '')
- if values[1] or (key in kwargs and kwargs[key]):
- controlfile += MakeDebianControlField(fieldname, kwargs[key], values[2])
- # Create the control.tar file
- tar = BytesIO()
- with gzip.GzipFile('control.tar.gz', mode='w', fileobj=tar, mtime=0) as gz:
- with tarfile.open('control.tar.gz', mode='w', fileobj=gz) as f:
- tarinfo = tarfile.TarInfo('control')
- controlfile_utf8 = six.ensure_binary(controlfile, 'utf-8')
- # Don't discard unicode characters when computing the size
- tarinfo.size = len(controlfile_utf8)
- f.addfile(tarinfo, fileobj=BytesIO(controlfile_utf8))
- if extrafiles:
- for name, (data, mode) in extrafiles.items():
- tarinfo = tarfile.TarInfo(name)
- tarinfo.size = len(data)
- tarinfo.mode = mode
- f.addfile(tarinfo, fileobj=BytesIO(six.ensure_binary(data, 'utf-8')))
- control = tar.getvalue()
- tar.close()
- return control
-
-
-def CreateDeb(output,
- data,
- preinst=None,
- postinst=None,
- prerm=None,
- postrm=None,
- config=None,
- templates=None,
- conffiles=None,
- **kwargs):
- """Create a full debian package."""
- extrafiles = {}
- if preinst:
- extrafiles['preinst'] = (preinst, 0o755)
- if postinst:
- extrafiles['postinst'] = (postinst, 0o755)
- if prerm:
- extrafiles['prerm'] = (prerm, 0o755)
- if postrm:
- extrafiles['postrm'] = (postrm, 0o755)
- if config:
- extrafiles['config'] = (config, 0o755)
- if templates:
- extrafiles['templates'] = (templates, 0o755)
- if conffiles:
- extrafiles['conffiles'] = ('\n'.join(conffiles) + '\n', 0o644)
- control = CreateDebControl(extrafiles=extrafiles, **kwargs)
-
- # Write the final AR archive (the deb package)
- with open(output, 'wb') as f:
- f.write(b'!<arch>\n') # Magic AR header
- AddArFileEntry(f, 'debian-binary', b'2.0\n')
- AddArFileEntry(f, 'control.tar.gz', control)
- # Tries to preserve the extension name
- ext = six.ensure_str(os.path.basename(data)).split('.')[-2:]
- if len(ext) < 2:
- ext = 'tar'
- elif ext[1] == 'tgz':
- ext = 'tar.gz'
- elif ext[1] == 'tar.bzip2':
- ext = 'tar.bz2'
- else:
- ext = '.'.join(ext)
- if ext not in ['tar.bz2', 'tar.gz', 'tar.xz', 'tar.lzma']:
- ext = 'tar'
- data_size = os.stat(data).st_size
- with open(data, 'rb') as datafile:
- AddArFileEntry(f, 'data.' + ext, datafile, content_len=data_size)
-
-
-def GetChecksumsFromFile(filename, hash_fns=None):
- """Computes MD5 and/or other checksums of a file.
-
- Args:
- filename: Name of the file.
- hash_fns: Mapping of hash functions.
- Default is {'md5': hashlib.md5}
-
- Returns:
- Mapping of hash names to hexdigest strings.
- { <hashname>: <hexdigest>, ... }
- """
- hash_fns = hash_fns or {'md5': hashlib.md5}
- checksums = {k: fn() for (k, fn) in hash_fns.items()}
-
- with open(filename, 'rb') as file_handle:
- while True:
- buf = file_handle.read(1048576) # 1 MiB
- if not buf:
- break
- for hashfn in checksums.values():
- hashfn.update(buf)
-
- return {k: fn.hexdigest() for (k, fn) in checksums.items()}
-
-
-def CreateChanges(output,
- deb_file,
- architecture,
- short_description,
- maintainer,
- package,
- version,
- section,
- priority,
- distribution,
- urgency,
- timestamp=0):
- """Create the changes file."""
- checksums = GetChecksumsFromFile(deb_file, {'md5': hashlib.md5,
- 'sha1': hashlib.sha1,
- 'sha256': hashlib.sha256})
- debsize = str(os.path.getsize(deb_file))
- deb_basename = os.path.basename(deb_file)
-
- changesdata = ''.join([
- MakeDebianControlField('Format', '1.8'),
- MakeDebianControlField('Date', time.ctime(timestamp)),
- MakeDebianControlField('Source', package),
- MakeDebianControlField('Binary', package),
- MakeDebianControlField('Architecture', architecture),
- MakeDebianControlField('Version', version),
- MakeDebianControlField('Distribution', distribution),
- MakeDebianControlField('Urgency', urgency),
- MakeDebianControlField('Maintainer', maintainer),
- MakeDebianControlField('Changed-By', maintainer),
- MakeDebianControlField('Description',
- '\n%s - %s' % (package, short_description)),
- MakeDebianControlField('Changes',
- ('\n%s (%s) %s; urgency=%s'
- '\nChanges are tracked in revision control.') %
- (package, version, distribution, urgency)),
- MakeDebianControlField(
- 'Files', '\n' + ' '.join(
- [checksums['md5'], debsize, section, priority, deb_basename])),
- MakeDebianControlField(
- 'Checksums-Sha1',
- '\n' + ' '.join([checksums['sha1'], debsize, deb_basename])),
- MakeDebianControlField(
- 'Checksums-Sha256',
- '\n' + ' '.join([checksums['sha256'], debsize, deb_basename]))
- ])
- with open(output, 'w') as changes_fh:
- changes_fh.write(six.ensure_binary(changesdata, 'utf-8').decode('utf-8'))
-
-
-def GetFlagValue(flagvalue, strip=True):
- if flagvalue:
- flagvalue = six.ensure_text(flagvalue, 'utf-8')
- if flagvalue[0] == '@':
- with open(flagvalue[1:], 'r') as f:
- flagvalue = six.ensure_text(f.read(), 'utf-8')
- if strip:
- return flagvalue.strip()
- return flagvalue
-
-
-def GetFlagValues(flagvalues):
- if flagvalues:
- return [GetFlagValue(f, False) for f in flagvalues]
- else:
- return None
-
-
-def main(unused_argv):
- CreateDeb(
- FLAGS.output,
- FLAGS.data,
- preinst=GetFlagValue(FLAGS.preinst, False),
- postinst=GetFlagValue(FLAGS.postinst, False),
- prerm=GetFlagValue(FLAGS.prerm, False),
- postrm=GetFlagValue(FLAGS.postrm, False),
- config=GetFlagValue(FLAGS.config, False),
- templates=GetFlagValue(FLAGS.templates, False),
- conffiles=GetFlagValues(FLAGS.conffile),
- package=FLAGS.package,
- version=GetFlagValue(FLAGS.version),
- description=GetFlagValue(FLAGS.description),
- maintainer=FLAGS.maintainer,
- section=FLAGS.section,
- architecture=FLAGS.architecture,
- depends=GetFlagValues(FLAGS.depends),
- suggests=FLAGS.suggests,
- enhances=FLAGS.enhances,
- preDepends=FLAGS.pre_depends,
- recommends=FLAGS.recommends,
- homepage=FLAGS.homepage,
- builtUsing=GetFlagValue(FLAGS.built_using),
- priority=FLAGS.priority,
- conflicts=FLAGS.conflicts,
- installedSize=GetFlagValue(FLAGS.installed_size))
- CreateChanges(
- output=FLAGS.changes,
- deb_file=FLAGS.output,
- architecture=FLAGS.architecture,
- short_description=GetFlagValue(FLAGS.description).split('\n')[0],
- maintainer=FLAGS.maintainer, package=FLAGS.package,
- version=GetFlagValue(FLAGS.version), section=FLAGS.section,
- priority=FLAGS.priority, distribution=FLAGS.distribution,
- urgency=FLAGS.urgency)
-
-if __name__ == '__main__':
- Makeflags()
- FLAGS = flags.FLAGS
- app.run(main)
diff --git a/tools/build_defs/pkg/pkg.bzl b/tools/build_defs/pkg/pkg.bzl
index 4f762f4..11fce9b 100644
--- a/tools/build_defs/pkg/pkg.bzl
+++ b/tools/build_defs/pkg/pkg.bzl
@@ -18,7 +18,6 @@
# Filetype to restrict inputs
tar_filetype = [".tar", ".tar.gz", ".tgz", ".tar.xz", ".tar.bz2"]
-deb_filetype = [".deb", ".udeb"]
def _remap(remap_paths, path):
"""If path starts with a key in remap_paths, rewrite it."""
@@ -35,7 +34,7 @@
"""Implementation of the pkg_tar rule."""
if ctx.attr._no_build_defs_pkg_flag[BuildSettingInfo].value:
- fail("The built-in version of pkg_deb has been removed. Please use" +
+ fail("The built-in version of pkg_tar has been removed. Please use" +
" https://github.com/bazelbuild/rules_pkg/blob/master/pkg.")
# Compute the relative path
@@ -126,122 +125,6 @@
use_default_shell_env = True,
)
-def _pkg_deb_impl(ctx):
- """The implementation for the pkg_deb rule."""
-
- if ctx.attr._no_build_defs_pkg_flag[BuildSettingInfo].value:
- fail("The built-in version of pkg_deb has been removed. Please use" +
- " https://github.com/bazelbuild/rules_pkg/blob/master/pkg.")
-
- files = [ctx.file.data]
- args = [
- "--output=" + ctx.outputs.deb.path,
- "--changes=" + ctx.outputs.changes.path,
- "--data=" + ctx.file.data.path,
- "--package=" + ctx.attr.package,
- "--architecture=" + ctx.attr.architecture,
- "--maintainer=" + ctx.attr.maintainer,
- ]
- if ctx.attr.preinst:
- args += ["--preinst=@" + ctx.file.preinst.path]
- files += [ctx.file.preinst]
- if ctx.attr.postinst:
- args += ["--postinst=@" + ctx.file.postinst.path]
- files += [ctx.file.postinst]
- if ctx.attr.prerm:
- args += ["--prerm=@" + ctx.file.prerm.path]
- files += [ctx.file.prerm]
- if ctx.attr.postrm:
- args += ["--postrm=@" + ctx.file.postrm.path]
- files += [ctx.file.postrm]
- if ctx.attr.config:
- args += ["--config=@" + ctx.file.config.path]
- files += [ctx.file.config]
- if ctx.attr.templates:
- args += ["--templates=@" + ctx.file.templates.path]
- files += [ctx.file.templates]
-
- # Conffiles can be specified by a file or a string list
- if ctx.attr.conffiles_file:
- if ctx.attr.conffiles:
- fail("Both conffiles and conffiles_file attributes were specified")
- args += ["--conffile=@" + ctx.file.conffiles_file.path]
- files += [ctx.file.conffiles_file]
- elif ctx.attr.conffiles:
- args += ["--conffile=%s" % cf for cf in ctx.attr.conffiles]
-
- # Version and description can be specified by a file or inlined
- if ctx.attr.version_file:
- if ctx.attr.version:
- fail("Both version and version_file attributes were specified")
- args += ["--version=@" + ctx.file.version_file.path]
- files += [ctx.file.version_file]
- elif ctx.attr.version:
- args += ["--version=" + ctx.attr.version]
- else:
- fail("Neither version_file nor version attribute was specified")
-
- if ctx.attr.description_file:
- if ctx.attr.description:
- fail("Both description and description_file attributes were specified")
- args += ["--description=@" + ctx.file.description_file.path]
- files += [ctx.file.description_file]
- elif ctx.attr.description:
- args += ["--description=" + ctx.attr.description]
- else:
- fail("Neither description_file nor description attribute was specified")
-
- # Built using can also be specified by a file or inlined (but is not mandatory)
- if ctx.attr.built_using_file:
- if ctx.attr.built_using:
- fail("Both build_using and built_using_file attributes were specified")
- args += ["--built_using=@" + ctx.file.built_using_file.path]
- files += [ctx.file.built_using_file]
- elif ctx.attr.built_using:
- args += ["--built_using=" + ctx.attr.built_using]
-
- if ctx.attr.depends_file:
- if ctx.attr.depends:
- fail("Both depends and depends_file attributes were specified")
- args += ["--depends=@" + ctx.file.depends_file.path]
- files += [ctx.file.depends_file]
- elif ctx.attr.depends:
- args += ["--depends=" + d for d in ctx.attr.depends]
-
- if ctx.attr.priority:
- args += ["--priority=" + ctx.attr.priority]
- if ctx.attr.section:
- args += ["--section=" + ctx.attr.section]
- if ctx.attr.homepage:
- args += ["--homepage=" + ctx.attr.homepage]
-
- args += ["--distribution=" + ctx.attr.distribution]
- args += ["--urgency=" + ctx.attr.urgency]
- args += ["--suggests=" + d for d in ctx.attr.suggests]
- args += ["--enhances=" + d for d in ctx.attr.enhances]
- args += ["--conflicts=" + d for d in ctx.attr.conflicts]
- args += ["--pre_depends=" + d for d in ctx.attr.predepends]
- args += ["--recommends=" + d for d in ctx.attr.recommends]
-
- ctx.actions.run(
- executable = ctx.executable.make_deb,
- arguments = args,
- inputs = files,
- outputs = [ctx.outputs.deb, ctx.outputs.changes],
- mnemonic = "MakeDeb",
- )
- ctx.actions.run_shell(
- command = "ln -s %s %s" % (ctx.outputs.deb.basename, ctx.outputs.out.path),
- inputs = [ctx.outputs.deb],
- outputs = [ctx.outputs.out],
- )
- output_groups = {"out": [ctx.outputs.out]}
- if hasattr(ctx.outputs, "deb"):
- output_groups["deb"] = [ctx.outputs.deb]
- if hasattr(ctx.outputs, "changes"):
- output_groups["changes"] = [ctx.outputs.changes]
- return OutputGroupInfo(**output_groups)
-
# A rule for creating a tar file, see README.md
_real_pkg_tar = rule(
implementation = _pkg_tar_impl,
@@ -295,69 +178,3 @@
out = kwargs["name"] + "." + extension,
**kwargs
)
-
-# A rule for creating a deb file, see README.md
-_pkg_deb = rule(
- implementation = _pkg_deb_impl,
- attrs = {
- "data": attr.label(mandatory = True, allow_single_file = tar_filetype),
- "package": attr.string(mandatory = True),
- "architecture": attr.string(default = "all"),
- "distribution": attr.string(default = "unstable"),
- "urgency": attr.string(default = "medium"),
- "maintainer": attr.string(mandatory = True),
- "preinst": attr.label(allow_single_file = True),
- "postinst": attr.label(allow_single_file = True),
- "prerm": attr.label(allow_single_file = True),
- "postrm": attr.label(allow_single_file = True),
- "config": attr.label(allow_single_file = True),
- "templates": attr.label(allow_single_file = True),
- "conffiles_file": attr.label(allow_single_file = True),
- "conffiles": attr.string_list(default = []),
- "version_file": attr.label(allow_single_file = True),
- "version": attr.string(),
- "description_file": attr.label(allow_single_file = True),
- "description": attr.string(),
- "built_using_file": attr.label(allow_single_file = True),
- "built_using": attr.string(),
- "priority": attr.string(),
- "section": attr.string(),
- "homepage": attr.string(),
- "depends": attr.string_list(default = []),
- "depends_file": attr.label(allow_single_file = True),
- "suggests": attr.string_list(default = []),
- "enhances": attr.string_list(default = []),
- "conflicts": attr.string_list(default = []),
- "predepends": attr.string_list(default = []),
- "recommends": attr.string_list(default = []),
- # Implicit dependencies.
- "make_deb": attr.label(
- default = Label("//tools/build_defs/pkg:make_deb"),
- cfg = "exec",
- executable = True,
- allow_files = True,
- ),
- # Outputs.
- "out": attr.output(mandatory = True),
- "deb": attr.output(mandatory = True),
- "changes": attr.output(mandatory = True),
- "_no_build_defs_pkg_flag": attr.label(
- default = "//tools/build_defs/pkg:incompatible_no_build_defs_pkg",
- ),
- },
-)
-
-def pkg_deb(name, package, **kwargs):
- """Creates a deb file. See README.md."""
- version = kwargs.get("version", "")
- architecture = kwargs.get("architecture", "all")
- out_deb = "%s_%s_%s.deb" % (package, version, architecture)
- out_changes = "%s_%s_%s.changes" % (package, version, architecture)
- _pkg_deb(
- name = name,
- package = package,
- out = name + ".deb",
- deb = out_deb,
- changes = out_changes,
- **kwargs
- )
diff --git a/tools/build_defs/pkg/testdata/config b/tools/build_defs/pkg/testdata/config
deleted file mode 100644
index d39edc7..0000000
--- a/tools/build_defs/pkg/testdata/config
+++ /dev/null
@@ -1 +0,0 @@
-# test config file