blob: 5ad46e19eee408b97fe14656edc82bd3584f3203 [file] [log] [blame]
Philipp Schrader0e19c602018-03-07 21:07:22 -08001#!/usr/bin/env python3
2
3import sys
4import os
5import re
6import subprocess
7import tempfile
8import argparse
9import hashlib
10
11def get_deps(package):
12 out = subprocess.check_output(["apt-rdepends", package])
13 deps = out.splitlines()
14 return set([dep for dep in deps if not dep.startswith(b" ")])
15
16def get_all_deps(packages):
17 deps = set()
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080018 for package in packages or ():
Philipp Schrader0e19c602018-03-07 21:07:22 -080019 deps.update(get_deps(package))
20 return deps
21
Brian Silverman6470f442018-08-05 12:08:16 -070022def map_virtual_packages(packages):
23 '''Maps known virtual packages to the preferred concrete packages which
24 provide them.'''
25 for package in packages:
26 if package == b'python-numpy-abi9':
27 yield b'python-numpy'
28 continue
29 if package == b'python3-numpy-abi9':
30 yield b'python3-numpy'
31 continue
32 yield package
33
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080034def download_deps(packages, excludes, force_includes):
Philipp Schrader0e19c602018-03-07 21:07:22 -080035 deps = get_all_deps(packages)
36 exclude_deps = get_all_deps(excludes)
37 deps -= exclude_deps
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080038 force_include_deps = get_all_deps(force_includes)
39 deps |= force_include_deps
Brian Silverman6470f442018-08-05 12:08:16 -070040 subprocess.check_call([b"apt-get", b"download"] + list(map_virtual_packages(deps)))
Philipp Schrader0e19c602018-03-07 21:07:22 -080041
42def fixup_files():
43 # Gotta remove those pesky epoch numbers in the file names. Bazel doesn't
44 # like them.
45 regex = re.compile(".%3a")
46 contents = os.listdir(os.getcwd())
47 for deb in contents:
48 new_name = regex.sub("", deb)
49 if new_name != deb:
50 os.rename(deb, new_name)
51
52def sha256_checksum(filename, block_size=65536):
53 sha256 = hashlib.sha256()
54 with open(filename, 'rb') as f:
55 for block in iter(lambda: f.read(block_size), b''):
56 sha256.update(block)
57 return sha256.hexdigest()
58
59def print_file_list():
60 contents = os.listdir(os.getcwd())
61 contents.sort()
62 print("_files = {")
63 for deb in contents:
64 print(' "%s": "%s",' % (deb, sha256_checksum(deb)))
65 print("}")
66
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080067_ALWAYS_EXCLUDE = [
68 "debconf",
69 "debconf-2.0",
70 "dpkg",
71 "install-info",
72 "libc-dev",
73 "libc6",
74 "libc6-dev",
75]
76
Philipp Schrader0e19c602018-03-07 21:07:22 -080077def main(argv):
78 parser = argparse.ArgumentParser()
79 parser.add_argument("--exclude", "-e", type=str, action="append", help="A package to exclude from the list")
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080080 parser.add_argument("--force-include", type=str, action="append", help="Force include this and its dependencies. Even if listed in excludes.")
Philipp Schrader0e19c602018-03-07 21:07:22 -080081 parser.add_argument("package", nargs="+", help="The packages to download.")
82 args = parser.parse_args(argv[1:])
83 folder = tempfile.mkdtemp()
84 os.chdir(folder)
85 excludes = args.exclude or []
86 # Exclude common packages that don't make sense to include in everything all
87 # the time.
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080088 excludes += _ALWAYS_EXCLUDE
89 download_deps(args.package, excludes, args.force_include)
Philipp Schrader0e19c602018-03-07 21:07:22 -080090 fixup_files()
91 print_file_list()
92 print("Your packages are all in %s" % folder)
93
94if __name__ == "__main__":
95 sys.exit(main(sys.argv))