Ejemplo n.º 1
0
    def write_record(self, bdist_dir, distinfo_dir):
        from wheel.util import urlsafe_b64encode

        record_path = os.path.join(distinfo_dir, 'RECORD')
        record_relpath = os.path.relpath(record_path, bdist_dir)

        def walk():
            for dir, dirs, files in os.walk(bdist_dir):
                dirs.sort()
                for f in sorted(files):
                    yield os.path.join(dir, f)

        def skip(path):
            """Wheel hashes every possible file."""
            return (path == record_relpath)

        with open_for_csv(record_path, 'w+') as record_file:
            writer = csv.writer(record_file)
            for path in walk():
                relpath = os.path.relpath(path, bdist_dir)
                if skip(relpath):
                    hash = ''
                    size = ''
                else:
                    with open(path, 'rb') as f:
                        data = f.read()
                    digest = hashlib.sha256(data).digest()
                    hash = 'sha256=' + native(urlsafe_b64encode(digest))
                    size = len(data)
                record_path = os.path.relpath(
                    path, bdist_dir).replace(os.path.sep, '/')
                writer.writerow((record_path, hash, size))
Ejemplo n.º 2
0
def write_record(bdist_dir, distinfo_dir):

    record_path = os.path.join(distinfo_dir, 'RECORD')
    record_relpath = os.path.relpath(record_path, bdist_dir)

    def walk():
        for dir, dirs, files in os.walk(bdist_dir):
            dirs.sort()
            for f in sorted(files):
                yield os.path.join(dir, f)

    def skip(path):
        """Wheel hashes every possible file."""
        return (path == record_relpath)

    with open_for_csv(record_path, 'w+') as record_file:
        writer = csv.writer(record_file)
        for path in walk():
            relpath = os.path.relpath(path, bdist_dir)
            if skip(relpath):
                hash = ''
                size = ''
            else:
                with open(path, 'rb') as f:
                    data = f.read()
                digest = hashlib.sha256(data).digest()
                hash = 'sha256=' + native(urlsafe_b64encode(digest))
                size = len(data)
            record_path = os.path.relpath(path,
                                          bdist_dir).replace(os.path.sep, '/')
            writer.writerow((record_path, hash, size))
Ejemplo n.º 3
0
    def write_record(self, bdist_dir, distinfo_dir):
        from wheel.util import urlsafe_b64encode

        record_path = os.path.join(distinfo_dir, "RECORD")
        record_relpath = os.path.relpath(record_path, bdist_dir)

        def walk():
            for dir, dirs, files in os.walk(bdist_dir):
                dirs.sort()
                for f in sorted(files):
                    yield os.path.join(dir, f)

        def skip(path):
            """Wheel hashes every possible file."""
            return path == record_relpath

        with open_for_csv(record_path, "w+") as record_file:
            writer = csv.writer(record_file)
            for path in walk():
                relpath = os.path.relpath(path, bdist_dir)
                if skip(relpath):
                    hash = ""
                    size = ""
                else:
                    with open(path, "rb") as f:
                        data = f.read()
                    digest = hashlib.sha256(data).digest()
                    hash = "sha256=" + native(urlsafe_b64encode(digest))
                    size = len(data)
                record_path = os.path.relpath(path, bdist_dir).replace(
                    os.path.sep, "/")
                writer.writerow((record_path, hash, size))
Ejemplo n.º 4
0
def rewrite_record(bdist_dir):
    """ Rewrite RECORD file with hashes for all files in `wheel_sdir`

    Copied from :method:`wheel.bdist_wheel.bdist_wheel.write_record`

    Will also unsign wheel

    Parameters
    ----------
    bdist_dir : str
        Path of unpacked wheel file
    """
    info_dir = _dist_info_dir(bdist_dir)
    record_path = pjoin(info_dir, 'RECORD')
    record_relpath = relpath(record_path, bdist_dir)
    # Unsign wheel - because we're invalidating the record hash
    sig_path = pjoin(info_dir, 'RECORD.jws')
    if exists(sig_path):
        os.unlink(sig_path)

    def walk():
        for dir, dirs, files in os.walk(bdist_dir):
            for f in files:
                yield pjoin(dir, f)

    def skip(path):
        """Wheel hashes every possible file."""
        return path == record_relpath

    with open_for_csv(record_path, 'w+') as record_file:
        writer = csv.writer(record_file)
        for path in walk():
            relative_path = relpath(path, bdist_dir)
            if skip(relative_path):
                hash = ''
                size = ''
            else:
                with open(path, 'rb') as f:
                    data = f.read()
                digest = hashlib.sha256(data).digest()
                hash = 'sha256=' + native(urlsafe_b64encode(digest))
                size = len(data)
            record_path = relpath(path, bdist_dir).replace(psep, '/')
            writer.writerow((record_path, hash, size))
Ejemplo n.º 5
0
def rewrite_record(bdist_dir):
    """ Rewrite RECORD file with hashes for all files in `wheel_sdir`

    Copied from :method:`wheel.bdist_wheel.bdist_wheel.write_record`

    Will also unsign wheel

    Parameters
    ----------
    bdist_dir : str
        Path of unpacked wheel file
    """
    info_dir = _dist_info_dir(bdist_dir)
    record_path = pjoin(info_dir, 'RECORD')
    record_relpath = relpath(record_path, bdist_dir)
    # Unsign wheel - because we're invalidating the record hash
    sig_path = pjoin(info_dir, 'RECORD.jws')
    if exists(sig_path):
        os.unlink(sig_path)

    def walk():
        for dir, dirs, files in os.walk(bdist_dir):
            for f in files:
                yield pjoin(dir, f)

    def skip(path):
        """Wheel hashes every possible file."""
        return (path == record_relpath)

    with open_for_csv(record_path, 'w+') as record_file:
        writer = csv.writer(record_file)
        for path in walk():
            relative_path = relpath(path, bdist_dir)
            if skip(relative_path):
                hash = ''
                size = ''
            else:
                with open(path, 'rb') as f:
                    data = f.read()
                digest = hashlib.sha256(data).digest()
                hash = 'sha256=' + native(urlsafe_b64encode(digest))
                size = len(data)
            record_path = relpath(path, bdist_dir).replace(psep, '/')
            writer.writerow((record_path, hash, size))
Ejemplo n.º 6
0
    def add_files(self, files_to_add=None, basedir='.'):

        if files_to_add == None or len(files_to_add) == 0:
            return

        records = ZipPackageVerifier(self.filename).get_records()

        if (len(records) < 1):
            raise ValueError('Invalid wheel file no records found')

        last_record_name = records[0]
#         new_record_name = "RECORD.{}".format(len(records))
# 
        tmp_dir = tempfile.mkdtemp()
        try:
            record_path = '/'.join((self.distinfo_name, last_record_name))
            tmp_new_record_file = '/'.join((tmp_dir, self.distinfo_name, 
                                            last_record_name))
            self.zipfile.extract('/'.join((self.distinfo_name, last_record_name)), 
                                 path = tmp_dir)

            self.remove_files('/'.join((self.distinfo_name, 'config')))

            with closing(open_for_csv(tmp_new_record_file,"a+")) as record_file:
                writer = csv.writer(record_file)


                if files_to_add:
                    if 'config_file' in files_to_add.keys():
                        try:
                            data = open(files_to_add['config_file']).read()
                        except OSError as e:
                            _log.error("couldn't access {}" % files_to_add['config_file'])
                            raise

                        self.zipfile.writestr("%s/%s" % (self.distinfo_name, 'config'),
                                              data)

                        (hash_data, size, digest) = self._record_digest(data)
                        record_path = '/'.join((self.distinfo_name, 'config'))
                        writer.writerow((record_path, hash_data, size))

                    if 'contract' in files_to_add.keys() and files_to_add['contract'] is not None:
                        try:
                            data = open(files_to_add['contract']).read()
                        except OSError as e:
                            _log.error("couldn't access {}" % files_to_add['contract'])
                            raise

                        if files_to_add['contract'] != 'execreqs.json':
                            msg = 'WARNING: renaming passed contract file: {}'.format(
                                                        files_to_add['contract'])
                            msg += ' to execreqs.json'
                            sys.stderr.write(msg)
                            _log.warn(msg)

                        self.zipfile.writestr("%s/%s" % (self.distinfo_name, 'execreqs.json'),
                                              data)
                        (hash_data, size, digest) = self._record_digest(data)
                        record_path = '/'.join((self.distinfo_name, 'execreqs.json'))
                        writer.writerow((record_path, hash_data, size))


                    self.__setupzipfile__()

            self.pop_records_file()

            new_record_content = open(tmp_new_record_file, 'r').read()
            self.zipfile.writestr(self.distinfo_name+"/"+last_record_name,
                    new_record_content)

            self.zipfile.close()
            self.__setupzipfile__()
        finally:
            shutil.rmtree(tmp_dir, True)
Ejemplo n.º 7
0
    def install(self, force=False, overrides={}):
        """
        Install the wheel into site-packages.
        """

        # Utility to get the target directory for a particular key
        def get_path(key):
            return overrides.get(key) or self.install_paths[key]

        # The base target location is either purelib or platlib
        if self.parsed_wheel_info['Root-Is-Purelib'] == 'true':
            root = get_path('purelib')
        else:
            root = get_path('platlib')

        # Parse all the names in the archive
        name_trans = {}
        for info in self.zipfile.infolist():
            name = info.filename
            # Zip files can contain entries representing directories.
            # These end in a '/'.
            # We ignore these, as we create directories on demand.
            if name.endswith('/'):
                continue

            # Pathnames in a zipfile namelist are always /-separated.
            # In theory, paths could start with ./ or have other oddities
            # but this won't happen in practical cases of well-formed wheels.
            # We'll cover the simple case of an initial './' as it's both easy
            # to do and more common than most other oddities.
            if name.startswith('./'):
                name = name[2:]

            # Split off the base directory to identify files that are to be
            # installed in non-root locations
            basedir, sep, filename = name.partition('/')
            if sep and basedir == self.datadir_name:
                # Data file. Target destination is elsewhere
                key, sep, filename = filename.partition('/')
                if not sep:
                    raise ValueError(
                        "Invalid filename in wheel: {0}".format(name))
                target = get_path(key)
            else:
                # Normal file. Target destination is root
                key = ''
                target = root
                filename = name

            # Map the actual filename from the zipfile to its intended target
            # directory and the pathname relative to that directory.
            dest = os.path.normpath(os.path.join(target, filename))
            name_trans[info] = (key, target, filename, dest)

        # We're now ready to start processing the actual install. The process
        # is as follows:
        #   1. Prechecks - is the wheel valid, is its declared architecture
        #      OK, etc. [[Responsibility of the caller]]
        #   2. Overwrite check - do any of the files to be installed already
        #      exist?
        #   3. Actual install - put the files in their target locations.
        #   4. Update RECORD - write a suitably modified RECORD file to
        #      reflect the actual installed paths.

        if not force:
            for info, v in name_trans.items():
                k = info.filename
                key, target, filename, dest = v
                if os.path.exists(dest):
                    raise ValueError(
                        "Wheel file {0} would overwrite {1}. Use force if this is intended"
                        .format(k, dest))

        # Get the name of our executable, for use when replacing script
        # wrapper hashbang lines.
        # We encode it using getfilesystemencoding, as that is "the name of
        # the encoding used to convert Unicode filenames into system file
        # names".
        exename = sys.executable.encode(sys.getfilesystemencoding())
        record_data = []
        record_name = self.distinfo_name + '/RECORD'
        for info, (key, target, filename, dest) in name_trans.items():
            name = info.filename
            source = self.zipfile.open(info)
            # Skip the RECORD file
            if name == record_name:
                continue
            ddir = os.path.dirname(dest)
            if not os.path.isdir(ddir):
                os.makedirs(ddir)
            destination = HashingFile(open(dest, 'wb'))
            if key == 'scripts':
                hashbang = source.readline()
                if hashbang.startswith(b'#!python'):
                    hashbang = b'#!' + exename + binary(os.linesep)
                destination.write(hashbang)
            shutil.copyfileobj(source, destination)
            reldest = os.path.relpath(dest, root)
            reldest.replace(os.sep, '/')
            record_data.append(
                (reldest, destination.digest(), destination.length))
            destination.close()
            source.close()
            # preserve attributes (especially +x bit for scripts)
            attrs = info.external_attr >> 16
            if attrs:  # tends to be 0 if Windows.
                os.chmod(dest, info.external_attr >> 16)

        record_name = os.path.join(root, self.record_name)
        writer = csv.writer(open_for_csv(record_name, 'w+'))
        for reldest, digest, length in sorted(record_data):
            writer.writerow((reldest, digest, length))
        writer.writerow((self.record_name, '', ''))
Ejemplo n.º 8
0
    def install(self, force=False, overrides={}):
        """
        Install the wheel into site-packages.
        """

        # Utility to get the target directory for a particular key
        def get_path(key):
            return overrides.get(key) or self.install_paths[key]

        # The base target location is either purelib or platlib
        if self.parsed_wheel_info['Root-Is-Purelib'] == 'true':
            root = get_path('purelib')
        else:
            root = get_path('platlib')

        # Parse all the names in the archive
        name_trans = {}
        for info in self.zipfile.infolist():
            name = info.filename
            # Zip files can contain entries representing directories.
            # These end in a '/'.
            # We ignore these, as we create directories on demand.
            if name.endswith('/'):
                continue

            # Pathnames in a zipfile namelist are always /-separated.
            # In theory, paths could start with ./ or have other oddities
            # but this won't happen in practical cases of well-formed wheels.
            # We'll cover the simple case of an initial './' as it's both easy
            # to do and more common than most other oddities.
            if name.startswith('./'):
                name = name[2:]

            # Split off the base directory to identify files that are to be
            # installed in non-root locations
            basedir, sep, filename = name.partition('/')
            if sep and basedir == self.datadir_name:
                # Data file. Target destination is elsewhere
                key, sep, filename = filename.partition('/')
                if not sep:
                    raise ValueError("Invalid filename in wheel: {0}".format(name))
                target = get_path(key)
            else:
                # Normal file. Target destination is root
                key = ''
                target = root
                filename = name

            # Map the actual filename from the zipfile to its intended target
            # directory and the pathname relative to that directory.
            dest = os.path.normpath(os.path.join(target, filename))
            name_trans[info] = (key, target, filename, dest)

        # We're now ready to start processing the actual install. The process
        # is as follows:
        #   1. Prechecks - is the wheel valid, is its declared architecture
        #      OK, etc. [[Responsibility of the caller]]
        #   2. Overwrite check - do any of the files to be installed already
        #      exist?
        #   3. Actual install - put the files in their target locations.
        #   4. Update RECORD - write a suitably modified RECORD file to
        #      reflect the actual installed paths.

        if not force:
            for info, v in name_trans.items():
                k = info.filename
                key, target, filename, dest = v
                if os.path.exists(dest):
                    raise ValueError("Wheel file {0} would overwrite {1}. Use force if this is intended".format(k, dest))

        # Get the name of our executable, for use when replacing script
        # wrapper hashbang lines.
        # We encode it using getfilesystemencoding, as that is "the name of
        # the encoding used to convert Unicode filenames into system file
        # names".
        exename = sys.executable.encode(sys.getfilesystemencoding())
        record_data = []
        record_name = self.distinfo_name + '/RECORD'
        for info, (key, target, filename, dest) in name_trans.items():
            name = info.filename
            source = self.zipfile.open(info)
            # Skip the RECORD file
            if name == record_name:
                continue
            ddir = os.path.dirname(dest)
            if not os.path.isdir(ddir):
                os.makedirs(ddir)
            destination = HashingFile(open(dest, 'wb'))
            if key == 'scripts':
                hashbang = source.readline()
                if hashbang.startswith(b'#!python'):
                    hashbang = b'#!' + exename + binary(os.linesep)
                destination.write(hashbang)
            shutil.copyfileobj(source, destination)
            reldest = os.path.relpath(dest, root)
            reldest.replace(os.sep, '/')
            record_data.append((reldest, destination.digest(), destination.length))
            destination.close()
            source.close()
            # preserve attributes (especially +x bit for scripts)
            attrs = info.external_attr >> 16
            if attrs:  # tends to be 0 if Windows.
                os.chmod(dest, info.external_attr >> 16)

        record_name = os.path.join(root, self.record_name)
        writer = csv.writer(open_for_csv(record_name, 'w+'))
        for reldest, digest, length in sorted(record_data):
            writer.writerow((reldest, digest, length))
        writer.writerow((self.record_name, '', ''))
Ejemplo n.º 9
0
    def add_files(self, files_to_add=None, basedir='.'):

        if files_to_add == None or len(files_to_add) == 0:
            return

        records = ZipPackageVerifier(self.filename).get_records()

        if (len(records) < 1):
            raise ValueError('Invalid wheel file no records found')

        last_record_name = records[0]
        #         new_record_name = "RECORD.{}".format(len(records))
        #
        tmp_dir = tempfile.mkdtemp()
        try:
            record_path = '/'.join((self.distinfo_name, last_record_name))
            tmp_new_record_file = '/'.join(
                (tmp_dir, self.distinfo_name, last_record_name))
            self.zipfile.extract('/'.join(
                (self.distinfo_name, last_record_name)),
                                 path=tmp_dir)

            self.remove_files('/'.join((self.distinfo_name, 'config')))

            with closing(open_for_csv(tmp_new_record_file,
                                      "a+")) as record_file:
                writer = csv.writer(record_file)

                if files_to_add:
                    if 'config_file' in files_to_add.keys():
                        try:
                            data = open(files_to_add['config_file']).read()
                        except OSError as e:
                            _log.error("couldn't access {}" %
                                       files_to_add['config_file'])
                            raise

                        self.zipfile.writestr(
                            "%s/%s" % (self.distinfo_name, 'config'), data)

                        (hash_data, size, digest) = self._record_digest(data)
                        record_path = '/'.join((self.distinfo_name, 'config'))
                        writer.writerow((record_path, hash_data, size))

                    if 'identity_file' in files_to_add.keys():
                        try:
                            data = open(files_to_add['identity_file']).read()
                        except OSError as e:
                            _log.error("couldn't access {}" %
                                       files_to_add['identity_file'])
                            raise

                        self.zipfile.writestr(
                            "%s/%s" %
                            (self.distinfo_name, 'IDENTITY_TEMPLATE'), data)

                        (hash_data, size, digest) = self._record_digest(data)
                        record_path = '/'.join(
                            (self.distinfo_name, 'IDENTITY_TEMPLATE'))
                        writer.writerow((record_path, hash_data, size))

                    if 'contract' in files_to_add.keys(
                    ) and files_to_add['contract'] is not None:
                        try:
                            data = open(files_to_add['contract']).read()
                        except OSError as e:
                            _log.error("couldn't access {}" %
                                       files_to_add['contract'])
                            raise

                        if files_to_add['contract'] != 'execreqs.json':
                            msg = 'WARNING: renaming passed contract file: {}'.format(
                                files_to_add['contract'])
                            msg += ' to execreqs.json'
                            sys.stderr.write(msg)
                            _log.warn(msg)

                        self.zipfile.writestr(
                            "%s/%s" % (self.distinfo_name, 'execreqs.json'),
                            data)
                        (hash_data, size, digest) = self._record_digest(data)
                        record_path = '/'.join(
                            (self.distinfo_name, 'execreqs.json'))
                        writer.writerow((record_path, hash_data, size))

                    self.__setupzipfile__()

            self.pop_records_file()

            new_record_content = open(tmp_new_record_file, 'r').read()
            self.zipfile.writestr(self.distinfo_name + "/" + last_record_name,
                                  new_record_content)

            self.zipfile.close()
            self.__setupzipfile__()
        finally:
            shutil.rmtree(tmp_dir, True)