From 83f44e52c9a1034a833eae8c5a083940c689efc4 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Feb 05 2020 08:21:35 +0000 Subject: Don't extract all sources just to get at DESCRIPTION. We can use `TarFile.extractfile` to get at the DESCRIPTION directly. --- diff --git a/r2spec/r2spec_obj.py b/r2spec/r2spec_obj.py index 0489330..3e7ae0a 100644 --- a/r2spec/r2spec_obj.py +++ b/r2spec/r2spec_obj.py @@ -71,7 +71,8 @@ def setup_parser(prog): parser.add_argument('--force-dl', action='store_true', help='Enforce the download of the source, even if they are already on the system.') parser.add_argument('--keep-sources', action='store_true', - help='The extracted source on the current directory will not be removed.') + help='The source will be extracted in the current ' + 'directory.') parser.add_argument('--keep-logs', action='store_true', help='Keep the log file generated while building the rpm') parser.add_argument('--repo', default=None, @@ -278,11 +279,10 @@ class R2spec(object): if args.package or args.url: pack.download(args.force_dl) - pack.extract_sources() + if args.keep_sources: + pack.extract_sources() pack.get_description() pack.determine_arch() - if not args.keep_sources: - pack.remove_sources() spec = Spec(settings, pack, no_check=args.no_check, with_deps=args.with_deps) diff --git a/r2spec/rpackage.py b/r2spec/rpackage.py index 3b604ae..3c74524 100644 --- a/r2spec/rpackage.py +++ b/r2spec/rpackage.py @@ -24,12 +24,9 @@ from __future__ import absolute_import, division, print_function import os import re -import shutil import sys import tarfile -from tarfile import TarError - try: import configparser except ImportError: @@ -152,16 +149,26 @@ class RPackage(object): with open(sources, 'wb') as localfile: localfile.write(remotefile.read()) - def extract_sources(self): - """ Extract the sources into the current directory. """ + def open_sources(self): + """ Open the source tarball. """ sourcedir = get_rpm_tag('_sourcedir') tarball = "%s/%s" % (sourcedir, self.source) self.log.info("Opening: %s", tarball) try: - tar = tarfile.open(tarball) - tar.extractall() - tar.close() - except TarError as err: + return tarfile.open(tarball) + except tarfile.TarError as err: + self.log.debug("Error while extracting the tarball") + self.log.debug("ERROR: %s", err) + + def extract_sources(self): + """ Extract the sources into the current directory. """ + tar = self.open_sources() + if tar is None: + return + try: + with tar: + tar.extractall() + except tarfile.TarError as err: self.log.debug("Error while extracting the tarball") self.log.debug("ERROR: %s", err) @@ -183,35 +190,49 @@ class RPackage(object): from in them. """ description = '%s/DESCRIPTION' % self.name - self.log.info('Loading "%s"', description) + content = None if os.path.exists(self.name) and os.path.isfile(description): + self.log.info('Loading "%s" from extracted sources', description) try: - stream = open(description, 'rb') - content = stream.read() - stream.close() + with open(description, 'rb') as stream: + content = stream.read() except IOError as err: self.log.info( 'An error occurred while reading the DESCRIPTION file: %s', description) self.log.debug('ERROR: %s', err) - encoding = re.search(b'^Encoding: (.+)$', content, re.MULTILINE) - if encoding is not None: - content = content.decode(encoding.group(1).decode().strip()) + else: + self.log.info('Loading "%s" from tarball', description) + tar = self.open_sources() + if tar is not None: + try: + with tar: + with tar.extractfile(description) as stream: + content = stream.read() + except tarfile.TarError as err: + self.log.debug("Error while extracting the DESCRIPTION " + "file from the tarball") + self.log.debug("ERROR: %s", err) else: - content = content.decode('ascii') - key = None - for row in content.split('\n'): - if row.strip(): - pattern = re.compile(r"\w:*") - if pattern.match(row): - key, value = row.split(':', 1) - self.description[key.strip()] = value.strip() - else: - self.description[key] = self.description[key] + ' ' + \ - row.strip() + self.log.info('Could not find a DESCRIPTION file "%s" to read', + description) + return + + encoding = re.search(b'^Encoding: (.+)$', content, re.MULTILINE) + if encoding is not None: + content = content.decode(encoding.group(1).decode().strip()) else: - self.log.info('Could not find a DESCRIPTION file "%s" to read', - description) + content = content.decode('ascii') + key = None + for row in content.split('\n'): + if row.strip(): + pattern = re.compile(r"\w:*") + if pattern.match(row): + key, value = row.split(':', 1) + self.description[key.strip()] = value.strip() + else: + self.description[key] = self.description[key] + ' ' + \ + row.strip() def read_config(self): """ Read the general configuration containing the repo information @@ -221,18 +242,6 @@ class RPackage(object): parser.read(configfile) self.config = parser - def remove_sources(self): - """ Remove the source we extracted in the current working - directory. - """ - self.log.info('Removing extracted sources: "%s"', self.name) - try: - shutil.rmtree(self.name) - except (IOError, OSError) as err: - self.log.info('Could not remove the extracted sources: "%s"', - self.name) - self.log.debug('ERROR: %s', err) - def search_package_in_repo(self): """ Search a package in all R repositories listed in the general configuration file.