blob: 6331102e57d1c625139625f557efd57081935c91 [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
Tyler Chatow60671d32020-02-26 19:49:30 -080032 if package == b'libjack-0.125':
33 yield b'libjack-jackd2-0'
34 continue
35 if package == b'fonts-freefont':
36 yield b'fonts-freefont-ttf'
37 continue
38 if package == b'gsettings-backend':
39 yield b'dconf-gsettings-backend'
40 continue
41 if package == b'gdal-abi-2-4-0':
42 yield b'libgdal20'
43 continue
44 if package == b'libglu1':
45 yield b'libglu1-mesa'
46 continue
47 if package == b'liblapack.so.3':
48 yield b'liblapack3'
49 continue
50 if package == b'libopencl1':
51 yield b'ocl-icd-libopencl1'
52 continue
53 if package == b'libblas.so.3':
54 yield b'libblas3'
55 continue
Brian Silverman6470f442018-08-05 12:08:16 -070056 yield package
57
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080058def download_deps(packages, excludes, force_includes):
Philipp Schrader0e19c602018-03-07 21:07:22 -080059 deps = get_all_deps(packages)
60 exclude_deps = get_all_deps(excludes)
61 deps -= exclude_deps
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080062 force_include_deps = get_all_deps(force_includes)
63 deps |= force_include_deps
Brian Silverman6470f442018-08-05 12:08:16 -070064 subprocess.check_call([b"apt-get", b"download"] + list(map_virtual_packages(deps)))
Philipp Schrader0e19c602018-03-07 21:07:22 -080065
66def fixup_files():
67 # Gotta remove those pesky epoch numbers in the file names. Bazel doesn't
68 # like them.
69 regex = re.compile(".%3a")
70 contents = os.listdir(os.getcwd())
71 for deb in contents:
72 new_name = regex.sub("", deb)
73 if new_name != deb:
74 os.rename(deb, new_name)
75
76def sha256_checksum(filename, block_size=65536):
77 sha256 = hashlib.sha256()
78 with open(filename, 'rb') as f:
79 for block in iter(lambda: f.read(block_size), b''):
80 sha256.update(block)
81 return sha256.hexdigest()
82
83def print_file_list():
84 contents = os.listdir(os.getcwd())
85 contents.sort()
86 print("_files = {")
87 for deb in contents:
88 print(' "%s": "%s",' % (deb, sha256_checksum(deb)))
89 print("}")
90
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080091_ALWAYS_EXCLUDE = [
Tyler Chatow60671d32020-02-26 19:49:30 -080092 "dbus-session-bus",
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080093 "debconf",
94 "debconf-2.0",
Tyler Chatow60671d32020-02-26 19:49:30 -080095 "default-dbus-session-bus",
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080096 "dpkg",
97 "install-info",
98 "libc-dev",
99 "libc6",
100 "libc6-dev",
101]
102
Philipp Schrader0e19c602018-03-07 21:07:22 -0800103def main(argv):
104 parser = argparse.ArgumentParser()
105 parser.add_argument("--exclude", "-e", type=str, action="append", help="A package to exclude from the list")
Philipp Schraderaedfc5c2018-03-10 19:32:30 -0800106 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 -0800107 parser.add_argument("package", nargs="+", help="The packages to download.")
108 args = parser.parse_args(argv[1:])
109 folder = tempfile.mkdtemp()
110 os.chdir(folder)
111 excludes = args.exclude or []
112 # Exclude common packages that don't make sense to include in everything all
113 # the time.
Philipp Schraderaedfc5c2018-03-10 19:32:30 -0800114 excludes += _ALWAYS_EXCLUDE
115 download_deps(args.package, excludes, args.force_include)
Philipp Schrader0e19c602018-03-07 21:07:22 -0800116 fixup_files()
117 print_file_list()
118 print("Your packages are all in %s" % folder)
119
120if __name__ == "__main__":
121 sys.exit(main(sys.argv))