0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-19 19:42:19 +02:00
libsignal/bin/fetch_archive.py
Jordan Rose 9c02d7a8cd Pods: Change the podspec to download prebuilds
Rather than building the Rust parts of libsignal as part of `pod
install`, fetch them from build-artifacts.signal.org. This requires
adding

    ENV['LIBSIGNAL_FFI_PREBUILD_CHECKSUM'] = '...'

to the consuming Podfile. The referenced archives are downloaded to
~/Library/Caches/org.signal.libsignal, and are unarchived as part of
the build. (The archives are outside the build directory so that a
clean build does not require a new download.)

Building with LibSignalClient as a local pod is still supported; in
that case everything will refer to the local target/ directory
instead. Use swift/build_ffi.sh to build as usual.
2023-01-12 16:47:28 -08:00

80 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Copyright 2023 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
#
# This script is based on RingRTC's fetch-artifact.py,
# but simplified for using only as a helper for LibSignalClient.podspec.
import argparse
import hashlib
import os
import sys
import urllib.request
from typing import BinaryIO
UNVERIFIED_DOWNLOAD_NAME = "unverified.tmp"
def build_argument_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description='Download and verify a build artifact archive.')
parser.add_argument('-u', '--url',
required=True,
help='URL of an artifact archive')
parser.add_argument('-c', '--checksum',
required=True,
help='sha256sum of the unexpanded artifact archive')
parser.add_argument('-o', '--output-dir',
required=True,
help='Directory to store the archives in')
return parser
def download_if_needed(archive_file: str, url: str, checksum: str) -> BinaryIO:
try:
f = open(archive_file, 'rb')
digest = hashlib.sha256()
chunk = f.read1()
while chunk:
digest.update(chunk)
chunk = f.read1()
if digest.hexdigest() == checksum.lower():
return f
print("existing file '{}' has non-matching checksum {}; re-downloading...".format(archive_file, digest.hexdigest()), file=sys.stderr)
except FileNotFoundError:
pass
print("downloading {}...".format(archive_file), file=sys.stderr)
try:
with urllib.request.urlopen(url) as response:
digest = hashlib.sha256()
f = open(UNVERIFIED_DOWNLOAD_NAME, 'w+b')
chunk = response.read1()
while chunk:
digest.update(chunk)
f.write(chunk)
chunk = response.read1()
assert digest.hexdigest() == checksum.lower(), "expected {}, actual {}".format(checksum.lower(), digest.hexdigest())
os.replace(UNVERIFIED_DOWNLOAD_NAME, archive_file)
return f
except urllib.error.HTTPError as e:
print(e, e.filename, file=sys.stderr)
sys.exit(1)
def main() -> None:
parser = build_argument_parser()
args = parser.parse_args()
os.makedirs(os.path.abspath(args.output_dir), exist_ok=True)
os.chdir(args.output_dir)
archive_file = os.path.basename(args.url)
download_if_needed(archive_file, args.url, args.checksum)
main()