Exemple #1
0
    def __init__(self, config = None, db=None):
        self.config = config
        self.modules = {}
        self.raise_exception_on_warning=False

        if db is None:
            legacy_pkgdb_path = os.path.join(self.config.prefix, 'share', 'icbuild', 'packagedb.xml')
            new_pkgdb_path = os.path.join(self.config.top_builddir, 'packagedb.xml')
            if os.path.isfile(legacy_pkgdb_path):
                fileutils.rename(legacy_pkgdb_path, new_pkgdb_path)
            self.packagedb = packagedb.PackageDB(new_pkgdb_path, config)
        else:
            self.packagedb = db
Exemple #2
0
def unpack_archive(buildscript, localfile, target_directory, checkoutdir=None):
    """
    Unpack @localfile to @target_directory; if @checkoutdir is specified make
    sure the unpacked content gets into a directory by that name
    """
    if checkoutdir:
        final_target_directory = target_directory
        target_directory = tempfile.mkdtemp(dir=final_target_directory)

    ext = os.path.splitext(localfile)[-1]
    if ext == '.lzma' and has_command('lzcat.exe') and has_command('tar.exe'):
        buildscript.execute('lzcat -d "%s" | tar xf -' % localfile,
                cwd=target_directory)
    elif ext == '.xz' and has_command('xzcat.exe') and has_command('tar.exe'):
        buildscript.execute('xzcat -d "%s" | tar xf -' % localfile,
                cwd=target_directory)
    elif ext == '.bz2' and has_command('bunzip2.exe') and has_command('tar.exe'):
        buildscript.execute('bunzip2 -dc "%s" | tar xf -' % localfile,
                cwd=target_directory)
    elif ext in ('.gz', '.tgz') and has_command('gzip.exe') and has_command('tar.exe'):
        buildscript.execute('gzip -dc "%s" | tar xf -' % localfile,
                cwd=target_directory)
    elif ext == '.zip' and has_command('unzip.exe'):
        buildscript.execute('unzip "%s"' % localfile,
                cwd=target_directory)
    else:
        try:
            if tarfile.is_tarfile(localfile):
                unpack_tar_file(localfile, target_directory)
            elif zipfile.is_zipfile(localfile):
                unpack_zip_file(localfile, target_directory)
            else:
                raise CommandError('Failed to unpack %s (unknown archive type)' % localfile)
        except:
            raise CommandError('Failed to unpack %s' % localfile)

    if checkoutdir:
        # tarball has been extracted in $destdir/$tmp/, check, then move the
        # content of that directory
        if len(os.listdir(target_directory)) == 0:
            raise CommandError('Failed to unpack %s (empty file?)' % localfile)
        if len(os.listdir(target_directory)) == 1:
            # a single directory, just move it
            tmpdirname = os.path.join(target_directory, os.listdir(target_directory)[0])
            fileutils.rename(tmpdirname, os.path.join(final_target_directory, checkoutdir))
            os.rmdir(target_directory)
        else:
            # more files, just rename the temporary directory to the final name
            fileutils.rename(target_directory, os.path.join(final_target_directory, checkoutdir))
Exemple #3
0
    def _process_install_files(self, installroot, curdir, prefix, errors):
        """Strip the prefix from all files in the install root, and move
them into the prefix."""
        assert os.path.isdir(installroot) and os.path.isabs(installroot)
        assert os.path.isdir(curdir) and os.path.isabs(curdir)
        assert os.path.isdir(prefix) and os.path.isabs(prefix)

        if prefix.endswith('/'):
            prefix = prefix[:-1]

        num_copied = 0
        names = os.listdir(curdir)
        for filename in names:
            src_path = os.path.join(curdir, filename)
            assert src_path.startswith(installroot)
            dest_path = src_path[len(installroot):]
            try:
                if os.path.islink(src_path):
                    linkto = os.readlink(src_path)
                    if os.path.islink(dest_path) or os.path.isfile(dest_path):
                        os.unlink(dest_path)
                    os.symlink(linkto, dest_path)
                    os.unlink(src_path)
                    num_copied += 1
                elif os.path.isdir(src_path):
                    if os.path.exists(dest_path):
                        if not os.path.isdir(dest_path):
                            os.unlink(dest_path)
                            os.mkdir(dest_path)
                    else:
                        os.mkdir(dest_path)
                    num_copied += self._process_install_files(installroot,
                                                              src_path, prefix,
                                                              errors)
                    try:
                        os.rmdir(src_path)
                    except OSError:
                        # files remaining in buildroot, errors reported below
                        pass
                else:
                    try:
                        fileutils.rename(src_path, dest_path)
                        num_copied += 1
                    except OSError as e:
                        errors.append("%s: '%s'" % (str(e), dest_path))
            except OSError as e:
                errors.append(str(e))
        return num_copied
Exemple #4
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)
        self._clean_texinfo_dir_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + '-broken'
        destdir_prefix = os.path.join(destdir, stripped_prefix)
        new_contents = fileutils.accumulate_dirtree_contents(destdir_prefix)
        errors = []
        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info('Moving temporary DESTDIR %r into build prefix' % (destdir, ))
            num_copied = self._process_install_files(destdir, destdir_prefix,
                                                     buildscript.config.prefix,
                                                     errors)

            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_icbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != '', stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError as e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix." % {'num': len(remaining_files),
                                                                                                                            'dest': broken_name})
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
        else:
            save_broken_tree = True

        if save_broken_tree:
            if os.path.exists(broken_name):
                assert broken_name.startswith(buildscript.config.top_builddir)
                shutil.rmtree(broken_name)
            fileutils.rename(destdir, broken_name)
        else:
            assert destdir.startswith(buildscript.config.prefix)
            os.rmdir(destdir)

        if not install_succeeded:
            raise CommandError("Module failed to install into DESTDIR %(dest)r" % {'dest': broken_name})
        else:
            to_delete = set()
            previous_entry = buildscript.moduleset.packagedb.get(self.name)
            if previous_entry:
                previous_contents = previous_entry.get_manifest()
                if previous_contents:
                    to_delete.update(fileutils.filter_files_by_prefix(self.config, previous_contents))

            for filename in new_contents:
                to_delete.discard (os.path.join(self.config.prefix, filename))

            if to_delete:
                # paranoid double-check
                assert to_delete == set(fileutils.filter_files_by_prefix(self.config, to_delete))

                logging.info('%d files remaining from previous build' % (len(to_delete),))
                for (path, was_deleted, error_string) in fileutils.remove_files_and_dirs(to_delete, allow_nonempty_dirs=True):
                    if was_deleted:
                        logging.info('Deleted: %(file)r' % { 'file': path, })
                    elif error_string is None:
                        # We don't warn on not-empty directories
                        pass
                    else:
                        logging.warn("Failed to delete no longer installed file %(file)r: %(msg)s" % { 'file': path,
                                                                                                       'msg': error_string})

            buildscript.moduleset.packagedb.add(self.name, revision or '',
                                                new_contents,
                                                self.configure_cmd)

        if errors:
            raise CommandError('Install encountered errors: %(num)d '
                               'errors raised, %(files)d files copied. '
                               'The errors are:\n  %(err)s' %
                               {'num'   : len(errors),
                                'files' : num_copied,
                                'err'   : '\n  '.join(errors)})
        else:
            logging.info('Install complete: %d files copied' %
                         (num_copied, ))