~mrazik/jenkins-launchpad-plugin/fail-if-no-bug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import subprocess
from settings import logger
from bzrrecipe import BzrRecipe
import os
import re


class DputRunner:
    DEBFULLNAME = None
    DEBEMAIL = None
    versionFormat = ('{PACKAGE_VERSION}+bzr{BZR_REVISION}+' +
                     'pkg{PACKAGING_REVISION}~{DISTRIBUTION}1')
    distributions = []
    jenkinsBuildNumber = ''
    ppas = []

    def __init__(self, ppas, trunk, packagingBranch,
                 DEBFULLNAME, DEBEMAIL, revision=None,
                 versionFormat=None,
                 distributions=None, jenkinsBuildNumber='',
                 hooks=[], release_only=False):
        self.DEBFULLNAME = DEBFULLNAME
        self.DEBEMAIL = DEBEMAIL
        if versionFormat:
            self.versionFormat = versionFormat
        self.distributions = distributions
        self.jenkinsBuildNumber = jenkinsBuildNumber
        self.ppas = ppas
        self.trunk = trunk
        self.packagingBranch = packagingBranch
        self.revision = revision
        self.hooks = hooks
        self.release_only = release_only

    def formatVersionString(self, **kwargs):
        try:
            return self.versionFormat.format(**kwargs)
        except KeyError as error:
            logger.error('Unkown variable used in format string: ' +
                         error.message)
            return None

    def _run_hooks(self, hooks, cwd):
        hooks_path = '/usr/share/pbuilderjenkins/hooks/'
        for hook in sorted(hooks):
            logger.debug('Calling hack: %r', hook)
            subprocess.check_call([hooks_path + hook], cwd=cwd)

    def doDput(self, recipe, version_string, changelog_entry, distribution,
               ppa, release_only):
        logger.info('Going to dput version: ' + version_string)
        #export DEBFULLNAME=
        os.putenv('DEBFULLNAME', self.DEBFULLNAME)
        #export DEBEMAIL=
        os.putenv('DEBEMAIL', self.DEBEMAIL)
        #run few hooks from lp:pbuilderjenkins
        #as soon as there are non-H hooks added (which I think is unlikely)
        #the _run_hooks method needs to be refactored to honor the
        #first letter of the hook (see man pbuilder)
        self._run_hooks(self.hooks,
                        cwd=recipe.getTrunkDir())
        #dch -v $version $changelog -D $distribution
        if release_only:
            dch_call = ['dch', '--release', changelog_entry]
        else:
            dch_call = ['dch', '-b', '-v', version_string, changelog_entry,
                        '-D', distribution]
        logger.debug('Calling: %r', dch_call)
        subprocess.check_call(dch_call, cwd=recipe.getTrunkDir())
        filename = recipe.getSourceName() + '_'
        #if the version string starts with epoch ("^\d+:") then remove
        #the epoch from filename; it is not supposed to be there
        match = re.search("^\d+:(.*)$", version_string)
        if match:
            filename = filename + match.group(1)
        else:
            filename = filename + version_string
        #bzr builddeb -S
        debuild_call = ['bzr', 'builddeb', '-S']
        logger.debug('Calling: %r', debuild_call)
        subprocess.check_call(debuild_call, cwd=recipe.getTrunkDir())
        #dput $ppa *${version_string}_source.changes
        dput_call = ['dput', ppa, filename + '_source.changes']
        logger.debug('Calling: %r', dput_call)
        subprocess.check_call(dput_call, cwd=recipe.getBuildDir())
        #rm -f _source.ppa.upload
        rm_call = ['rm', '-f', filename + '_source.ppa.upload']
        logger.debug('Calling: %r', rm_call)
        subprocess.check_call(rm_call, cwd=recipe.getBuildDir())
        #revert the previous dch calls to get a clean changelog
        logger.debug('Reverting the change made by dch call')
        recipe.revert()

    def dput(self):
        if not self.distributions:
            logger.error('No distribution specified. Aborting dput.')
            return False

        recipe = BzrRecipe(self.trunk, self.packagingBranch, self.revision)

        for distribution in self.distributions:
            for ppa in self.ppas:
                formatedVersionString = self.formatVersionString(
                    PACKAGE_VERSION=recipe.getPackageVersion(),
                    BZR_REVISION=recipe.getTrunkRevno(),
                    PACKAGING_REVISION=recipe.getPackagingBranchRevno(),
                    JENKINS_BUILD_NUMBER=self.jenkinsBuildNumber,
                    DISTRIBUTION=distribution,
                    UPSTREAM_VERSION=recipe.getUpstreamVersion())
                if not formatedVersionString:
                    logger.error(
                        'Aborting dput as no format string was specified')
                    return False
                try:
                    self.doDput(recipe, formatedVersionString,
                                "Automatic build of revision " +
                                str(recipe.getTrunkRevno()),
                                distribution,
                                ppa, release_only=self.release_only)
                except subprocess.CalledProcessError as e:
                    logger.error('Command %s returned non-zero exit status %d',
                                 e.cmd, e.returncode)
                    return False
        recipe.cleanup()
        return True