fomu-workshop/get-toolchain.py
2021-11-29 14:41:41 +01:00

151 lines
4.2 KiB
Python
Executable File

#!/usr/bin/python
from __future__ import print_function
import hashlib
import json
import os
import sys
if sys.version_info.major == 2:
from urllib import urlretrieve
elif sys.version_info.major == 3:
from urllib.request import urlretrieve
else:
sys.stderr.write("Unknown Python version")
sys.exit(1)
def platform():
if 'linux' in sys.platform:
return 'Linux'
elif 'darwin' in sys.platform:
return 'macOS'
elif 'win' in sys.platform or 'msys' in sys.platform:
return 'Windows'
else:
return sys.platform
def reporthook(chunk, chunk_size, total_size):
# Be quiet on travis.
if os.environ.get('CI', False):
return
download_size = min(total_size, chunk * chunk_size)
print("Downloaded", download_size, "of", total_size, "%.2f%%" % (download_size*1.0/total_size*100.0))
def download_files(to_download):
for filename, url in to_download:
if "sha" in filename and "sha1" not in filename:
continue
if os.path.exists(filename):
continue
print("Downloading", url, "into", filename)
urlretrieve(url, filename, reporthook=reporthook)
def check_files(to_download):
sumfile = [f for f, u in to_download if f.endswith('sha1')][0]
print("Checksum file", sumfile)
sumfile_lines = [l.split() for l in open(sumfile, 'r').read().strip().splitlines()]
print(sumfile_lines)
error = False
for wanted_checksum, path in sumfile_lines:
filename = os.path.basename(path)
hasher = hashlib.sha1()
with open(filename, 'rb') as f:
while True:
data = f.read(4096)
if not data:
break
hasher.update(data)
actual_checksum = hasher.hexdigest()
if wanted_checksum != actual_checksum:
print(
filename, "removed broken file,",
"wanted checksum:", wanted_checksum,
"actual checksum:", actual_checksum,
)
os.unlink(filename)
error = True
else:
print(
filename, "good file,",
"matching checksum:", actual_checksum,
)
return not error
TOOLCHAIN = "https://api.github.com/repos/im-tomu/fomu-toolchain/releases/%s" % ("tags/nightly" if os.environ.get('CI', False) else "latest")
def get_toolchain_data():
if sys.version_info.major == 2:
from urllib2 import urlopen, Request
elif sys.version_info.major == 3:
from urllib.request import urlopen, Request
request = Request(TOOLCHAIN)
token = os.environ.get('GH_TOKEN', None)
if token:
request.add_header('Authorization', 'token %s' % token)
response = urlopen(request)
return json.loads(response.read())
def main(argv):
toolchain_data = get_toolchain_data()
if 'assets' not in toolchain_data:
import pprint
pprint.pprint(toolchain_data)
plat = platform()
print("Platform:", plat)
to_download = []
for asset in toolchain_data['assets']:
if plat not in asset['name']:
continue
to_download.append((asset['name'], asset['browser_download_url']))
while True:
download_files(to_download)
if check_files(to_download):
break
for tarball in [f for f, u in to_download if f.endswith(('.tar.gz', '.tar.xz'))]:
import tarfile
with tarfile.open(tarball) as tarf:
tarf.extractall()
for zipball in [f for f, u in to_download if f.endswith('.zip')]:
import zipfile
class ZipFileWithPerm(zipfile.ZipFile):
def _extract_member(self, member, targetpath, pwd):
if not isinstance(member, zipfile.ZipInfo):
member = self.getinfo(member)
targetpath = zipfile.ZipFile._extract_member(self, member, targetpath, pwd)
attr = member.external_attr >> 16
if attr != 0:
os.chmod(targetpath, attr)
return targetpath
with ZipFileWithPerm(zipball) as zipf:
zipf.extractall()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))