Example #1
0
def extract_tar(tarball):
    tmpdir = tempfile.gettempdir()
    process_run(['tar', 'xf', tarball, '-C', tmpdir])
    normalized_path = os.path.normpath(tarball)
    basename = os.path.splitext(
        os.path.splitext(os.path.basename(normalized_path))[0])[0]
    return os.path.join(tmpdir, basename)
Example #2
0
    def extract_tarball(self, tarball_file_path, destination):
        """Extract a tarball and return the path to it's files.

        The path may not be `destination` but `destination` plus the folder of the tarball, if the
        files are in that toplevel folder of the tarball. This method does the same as dpkg-source
        to determine the directory structure of the tarball. The strategy is mentioned in the
        best practices for .orig.tar.{gz,bz2,xz} files in section 6.7.8 and 6.7.81 of the following
        document.

        https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#pristinesource

        :type tarball_file_path: str
        :param destination: The desired destination directory
        :type destination: str
        :rtype: str
        :return: The path to the directory of the extracted content of the tarball
        """
        if not os.path.isfile(tarball_file_path):
            raise FileNotFoundError()

        # Extract the tarball to a temporary folder.
        tmpdir = tempfile.mkdtemp()
        process_run(['tar', 'xf', tarball_file_path, '-C', tmpdir])

        dir_content = filter(isdir, glob.glob(os.path.join(tmpdir, '*')))
        files = filter(isfile, dir_content)
        directories = filter(isdir, dir_content)

        # Check if the tarball contains only one directory.
        if len(directories) == 1 and len(files) == 0:
            source = directories[0]
            destination = os.path.join(destination, basename(source))
        else:
            msg = 'Tarballs not containing a single directory aren\'t supported so far'
            raise NotImplementedError(msg)

        if os.path.exists(destination):
            shutil.rmtree(destination)

        shutil.move(source, destination)
        log_command(['mv', source, destination])

        shutil.rmtree(tmpdir)
        log_command(['rm', '-r', tmpdir])

        return destination
Example #3
0
    def build(self, release_channel, tarball_file_path):
        """Build the debian packages.

        :param release_channel: Either 'stable' or 'nightly'
        :type release_channel: str
        :param tarball_file_path: The path of the tarball
        :type tarball_file_path: str
        """
        assert release_channel in ('stable', 'nightly')

        build_dir = DebPackageBuilder.get_empty_build_dir()
        tarball_source_dir = self.extract_tarball(tarball_file_path, build_dir)
        log_command(['cp', tarball_file_path, build_dir])
        shutil.copy(tarball_file_path, build_dir)
        shutil.move(
            os.path.join(build_dir, basename(tarball_file_path)),
            os.path.join(
                build_dir,
                self.determine_deb_tarball_filename(tarball_file_path)))

        # It's possible that debuild asks for user input. It seems that this behaviour cannot be
        # disabled, so the system call seems to be necessary at this point, to show the user that
        # debuild asks for input.
        process_run(['debuild', '-us', '-uc', '-sa'], cwd=tarball_source_dir)

        changes_filename = basename(
            glob.glob(os.path.join(build_dir, '*.changes'))[0])
        # Sign the changes file.
        print self._args
        if not self._args['--no-signing']:
            process_run([
                'debsign', '-k', self._args['--gpg-key-id'], changes_filename
            ], build_dir)

        print 'The packages have been created in %s' % build_dir

        if self._args['--publish']:
            self._publish_packages(build_dir, release_channel,
                                   changes_filename)
            print 'The packages have been published'
Example #4
0
    def _publish_packages(self, pkgdir, release_channel, changes_filename):
        """Publish a package using the `reprepro` command.

        :type pkgdir: str
        :type release_channel: str
        :type changes_filename: str
        """
        dirs = filter(isdir, glob.glob(os.path.join(pkgdir, '*')))
        if len(dirs) != 1:
            msg = 'The package directory has to contain exactly one directory "{}"'
            raise FileNotFoundError(msg.format(pkgdir))
        control_file = os.path.join(pkgdir, dirs[0], 'debian', 'control')

        obsolete_packages = []
        with open(control_file) as fcontrol:
            for line in fcontrol:
                match = re.search(r'^Package: (.*)\s*', line)
                if match:
                    obsolete_packages.append(match.group(1))

        # Remove deprecated nightly packages.
        if release_channel == 'nightly':
            cmd = [
                'reprepro', '--basedir', self._args['--publish'], 'remove',
                release_channel
            ]
            cmd += obsolete_packages

            process_run(cmd)

        # Publish packages.
        cmd = [
            'reprepro', '--basedir', self._args['--publish'], 'include',
            release_channel, changes_filename
        ]
        process_run(cmd, cwd=pkgdir)
Example #5
0
def test(arguments):
    for elem in arguments:
        argument, hint = elem
        if hint:
            print('Hint: {}'.format(hint))
        result = process_run(
            ['/usr/bin/python', get_abs_script_path()] + argument.split(' '))
        last_line = result.stdout.strip().split('\n')[-1]
        tarball_path = last_line.split(' ')[-1].strip()
        tempdir = extract_tar(tarball_path)

        print '-- Content of version.txt:'
        with open(os.path.join(tempdir, 'version.txt'), 'r') as fh:
            print(''.join(fh.readlines()).strip())

        print '-- First row of debian/changelog:'
        with open(os.path.join(tempdir, 'debian/changelog'), 'r') as fh:
            print fh.readline().strip()

        print
# *  Copyright (C) 2011-2016, it-novum GmbH <*****@*****.**>
# *
# *  openATTIC is free software; you can redistribute it and/or modify it
# *  under the terms of the GNU General Public License as published by
# *  the Free Software Foundation; version 2.
# *
# *  This package is distributed in the hope that it will be useful,
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# *  GNU General Public License for more details.

import os
import glob
import sys
from make_dist import process_run

home_dir = os.path.expanduser('~')
build_deb_packages_py_path = os.path.join(os.path.dirname(sys.argv[0]),
                                          'build_deb_packages.py')
tarballs = glob.glob(os.path.join(home_dir, 'src', '*.tar.bz2'))
print 'Creating packages of the following archives:'
for tarball in tarballs:
    print '\t{}'.format(tarball)
print
for i, tarball in enumerate(tarballs):
    msg = 'Creating package {} of {}'.format(i + 1, len(tarballs))
    print msg
    print '=' * len(msg) + '\n'
    process_run(['/usr/bin/python', build_deb_packages_py_path, tarball])
    print