Merge pull request #2365 from liugang/master

Improve mesonbuild/wrap/wrap.py
pull/2183/head
Jussi Pakkanen 7 years ago committed by GitHub
commit 011adc4bd2
  1. 60
      mesonbuild/wrap/wrap.py

@ -14,7 +14,7 @@
from .. import mlog from .. import mlog
import contextlib import contextlib
import urllib.request, os, hashlib, shutil import urllib.request, os, hashlib, shutil, tempfile, stat
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
@ -230,6 +230,8 @@ class Resolver:
def get_data(self, url): def get_data(self, url):
blocksize = 10 * 1024 blocksize = 10 * 1024
h = hashlib.sha256()
tmpfile = tempfile.NamedTemporaryFile(mode='wb', dir=self.cachedir, delete=False)
if url.startswith('https://wrapdb.mesonbuild.com'): if url.startswith('https://wrapdb.mesonbuild.com'):
resp = open_wrapdburl(url) resp = open_wrapdburl(url)
else: else:
@ -241,26 +243,34 @@ class Resolver:
dlsize = None dlsize = None
if dlsize is None: if dlsize is None:
print('Downloading file of unknown size.') print('Downloading file of unknown size.')
return resp.read() while True:
block = resp.read(blocksize)
if block == b'':
break
h.update(block)
tmpfile.write(block)
hashvalue = h.hexdigest()
return hashvalue, tmpfile.name
print('Download size:', dlsize) print('Download size:', dlsize)
print('Downloading: ', end='') print('Downloading: ', end='')
sys.stdout.flush() sys.stdout.flush()
printed_dots = 0 printed_dots = 0
blocks = []
downloaded = 0 downloaded = 0
while True: while True:
block = resp.read(blocksize) block = resp.read(blocksize)
if block == b'': if block == b'':
break break
downloaded += len(block) downloaded += len(block)
blocks.append(block) h.update(block)
tmpfile.write(block)
ratio = int(downloaded / dlsize * 10) ratio = int(downloaded / dlsize * 10)
while printed_dots < ratio: while printed_dots < ratio:
print('.', end='') print('.', end='')
sys.stdout.flush() sys.stdout.flush()
printed_dots += 1 printed_dots += 1
print('') print('')
return b''.join(blocks) hashvalue = h.hexdigest()
return hashvalue, tmpfile.name
def get_hash(self, data): def get_hash(self, data):
h = hashlib.sha256() h = hashlib.sha256()
@ -272,30 +282,47 @@ class Resolver:
ofname = os.path.join(self.cachedir, p.get('source_filename')) ofname = os.path.join(self.cachedir, p.get('source_filename'))
if os.path.exists(ofname): if os.path.exists(ofname):
mlog.log('Using', mlog.bold(packagename), 'from cache.') mlog.log('Using', mlog.bold(packagename), 'from cache.')
return else:
srcurl = p.get('source_url') srcurl = p.get('source_url')
mlog.log('Downloading', mlog.bold(packagename), 'from', mlog.bold(srcurl)) mlog.log('Downloading', mlog.bold(packagename), 'from', mlog.bold(srcurl))
srcdata = self.get_data(srcurl) dhash, tmpfile = self.get_data(srcurl)
dhash = self.get_hash(srcdata)
expected = p.get('source_hash') expected = p.get('source_hash')
if dhash != expected: if dhash != expected:
os.remove(tmpfile)
raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash)) raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash))
with open(ofname, 'wb') as f: os.rename(tmpfile, ofname)
f.write(srcdata)
if p.has_patch(): if p.has_patch():
purl = p.get('patch_url') purl = p.get('patch_url')
mlog.log('Downloading patch from', mlog.bold(purl)) mlog.log('Downloading patch from', mlog.bold(purl))
pdata = self.get_data(purl) phash, tmpfile = self.get_data(purl)
phash = self.get_hash(pdata)
expected = p.get('patch_hash') expected = p.get('patch_hash')
if phash != expected: if phash != expected:
os.remove(tmpfile)
raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash)) raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash))
filename = os.path.join(self.cachedir, p.get('patch_filename')) filename = os.path.join(self.cachedir, p.get('patch_filename'))
with open(filename, 'wb') as f: os.rename(tmpfile, filename)
f.write(pdata)
else: else:
mlog.log('Package does not require patch.') mlog.log('Package does not require patch.')
def copy_tree(self, root_src_dir, root_dst_dir):
"""
Copy directory tree. Overwrites also read only files.
"""
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
try:
os.remove(dst_file)
except PermissionError as exc:
os.chmod(dst_file, stat.S_IWUSR)
os.remove(dst_file)
shutil.copy2(src_file, dst_dir)
def extract_package(self, package): def extract_package(self, package):
if sys.version_info < (3, 5): if sys.version_info < (3, 5):
try: try:
@ -322,4 +349,9 @@ class Resolver:
pass pass
shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), extract_dir) shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), extract_dir)
if package.has_patch(): if package.has_patch():
try:
shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root) shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root)
except Exception:
with tempfile.TemporaryDirectory() as workdir:
shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), workdir)
self.copy_tree(workdir, self.subdir_root)

Loading…
Cancel
Save