lrossett / centos / centpkg

Forked from centos/centpkg 3 years ago
Clone
Brian Stinson 6e343c
# pylint: disable=line-too-long,abstract-class-not-used
Brian Stinson 6e343c
85a850
'''
85a850
    Top level function library for centpkg
85a850
'''
Brian Stinson 6e343c
85a850
# Author(s):
85a850
#            Jesse Keating <jkeating@redhat.com>
85a850
#            Pat Riehecky <riehecky@fnal.gov>
85a850
#            Brian Stinson <bstinson@ksu.edu>
85a850
#
85a850
# This program is free software; you can redistribute it and/or modify it
85a850
# under the terms of the GNU General Public License as published by the
85a850
# Free Software Foundation; either version 2 of the License, or (at your
85a850
# option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
85a850
# the full text of the license.
85a850
85a850
Brian Stinson ca61eb
import re
e7fd56
import warnings
Brian Stinson 2fb8a5
b201d4
import git
ebeaf1
from pyrpkg import Commands, rpkgError
b201d4
from pyrpkg.utils import cached_property
b201d4
96fedb
# doc/centpkg_man_page.py uses the 'cli' import
96fedb
from . import cli  # noqa
Brian Stinson 6e343c
from .lookaside import StreamLookasideCache, SIGLookasideCache
b201d4
b201d4
b201d4
_DEFAULT_VERSION = '9'
Brian Stinson 2fb8a5
05c687
7ae64c
class DistGitDirectory(object):
7ae64c
86b0d3
    signame = None
b201d4
    centosversion = _DEFAULT_VERSION
86b0d3
    projectname = None
86b0d3
    releasename = None
639034
    distrobranch = False
b201d4
    repo = None
b201d4
    git_origin_substr = 'git@gitlab.com/redhat/centos-stream'
86b0d3
b201d4
    def __init__(self, branchtext, repo_path=None):
b201d4
        if repo_path:
4588ec
            # self.repo = git.cmd.Git(repo_path)
4588ec
            self.repo = git.repo.Repo(repo_path)
bb525a
        rhelbranchre = r'rhel-(?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<appstream>\d+))?'
Brian Stinson 3edf28
        sigtobranchre = r'c(?P<centosversion>\d+[s]?)-sig-(?P<signame>\w+)-?(?P<projectname>\w+)?-?(?P<releasename>\w+)?'
639034
        distrobranchre = r'c(?P<centosversion>\d+)-?(?P<projectname>\w+)?'
e7fd56
        oldbranchre = r'(?P<signame>\w+)(?P<centosversion>\d)'
bb525a
        rhelmatch = re.search(rhelbranchre, branchtext)
639034
        sigmatch = re.match(sigtobranchre, branchtext)
639034
        distromatch = re.match(distrobranchre, branchtext)
e7fd56
        oldbranchmatch = re.match(oldbranchre, branchtext)
bb525a
        if rhelmatch:
bb525a
            gd = rhelmatch.groupdict()
bb525a
            self.distrobranch = True
bb525a
            self.signame = 'centos'
bb525a
            self.centosversion = gd['major']
bb525a
        elif sigmatch:
639034
            gd = sigmatch.groupdict()
9af8c4
            self.signame = gd['signame']
9af8c4
            self.centosversion = gd['centosversion']
7ae64c
35f2c1
            # Users have the option to specify (or not specify) common in their
35f2c1
            # git repos. Ww need to handle these cases because common is not a
35f2c1
            # project nor is it a release.
9af8c4
            if gd['projectname'] != 'common':
9af8c4
                self.projectname = gd['projectname']
9af8c4
            if gd['releasename'] != 'common':
9af8c4
                self.releasename = gd['releasename']
639034
        elif distromatch:
639034
            gd = distromatch.groupdict()
639034
            self.distrobranch = True
639034
            self.signame = 'centos'
639034
            self.centosversion = gd['centosversion']
639034
639034
            if gd['projectname'] != 'common':
639034
                self.projectname = gd['projectname']
e7fd56
        elif oldbranchmatch:
e7fd56
            warnings.warn("This branch is deprecated and will be removed soon",
e7fd56
                          DeprecationWarning)
639034
        else:
b201d4
            if not self.is_fork():
b201d4
                raise ValueError("Branchname: {0} is not valid".format(branchtext))
b201d4
            else:
b201d4
                self.distrobranch = True
b201d4
                self.signame = 'centos'
b201d4
                self.projectname = self.get_origin().split('_')[-1].replace('.git', '')
b201d4
b201d4
                warnings.warn('Remote "origin" was detected as a fork, ignoring branch name checking')
b201d4
b201d4
    def get_origin(self):
b201d4
        if self.repo is None:
b201d4
            return ''
4588ec
        if 'origin' not in self.repo.remotes:
4588ec
            return ''
4588ec
        urls = [u for u in self.repo.remotes['origin'].urls]
4588ec
        if len(urls) == 0:
4588ec
            return ''
4588ec
        return urls[0]
b201d4
b201d4
    def is_fork(self):
b201d4
        """
b201d4
        Check if origin remote repository is using a fork url.
b201d4
b201d4
        Returns
b201d4
        bool
b201d4
            A boolean flag indicating if origin remote url is using
b201d4
            a forked repository url.
b201d4
        """
b201d4
        # git+ssh://git@gitlab.com/redhat/centos-stream/rpms/binutils.git
b201d4
        if self.repo is None:
b201d4
            return False
b201d4
        return self.git_origin_substr not in self.get_origin()
b201d4
9af8c4
9af8c4
    @property
9af8c4
    def target(self):
9af8c4
        projectorcommon = self.projectname
9af8c4
        releaseorcommon = self.releasename
9af8c4
639034
        if self.distrobranch:
Brian Stinson 6e343c
            if self.centosversion not in ('6', '7'):
Brian Stinson 3edf28
                return 'c{}s-candidate'.format(self.centosversion)
Brian Stinson 3edf28
            else:
Brian Stinson 3edf28
                return '-'.join(filter(None, ['c'+self.centosversion,
Brian Stinson 3edf28
                                              projectorcommon]))
Brian Stinson 3edf28
9af8c4
        if not releaseorcommon:
9af8c4
            if not projectorcommon or projectorcommon == 'common':
9af8c4
                projectorcommon = 'common'
9af8c4
            else:
9af8c4
                releaseorcommon = 'common'
9af8c4
9af8c4
        return '-'.join(filter(None, [self.signame+self.centosversion,
9af8c4
                                      projectorcommon, releaseorcommon])) + '-el{0}'.format(self.centosversion)
9af8c4
a394b1
9af8c4
class Commands(Commands):
85a850
    '''
85a850
        For the pyrpkg commands with centpkg behavior
85a850
    '''
a394b1
    def __init__(self, *args, **kwargs):
85a850
        '''
85a850
            Init the object and some configuration details.
85a850
        '''
a394b1
        super(Commands, self).__init__(*args, **kwargs)
James Antill ed1405
        # For MD5 we want to use the old format of source files, the BSD format
James Antill ed1405
        # should only be used when configured for SHA512
James Antill ed1405
        self.source_entry_type = 'bsd' if self.lookasidehash != 'md5' else 'old'
6bb6df
        self.branchre = 'c\d{1,}(s)?(tream)?|master'
f5ba26
        self.lookaside_structure = None
f5ba26
f5ba26
    def update(self, config):
f5ba26
        if self.lookaside_structure is None:
f5ba26
            self.lookaside_structure = config.get('lookaside_structure', 'hash')
a394b1
a394b1
    @property
a394b1
    def distgitdir(self):
b201d4
        return DistGitDirectory(self.branch_merge, repo_path=self.path)
Brian Stinson 2fb8a5
a394b1
    @cached_property
a394b1
    def lookasidecache(self):
Brian Stinson 3edf28
        if self.distgitdir.distrobranch:
Brian Stinson 3edf28
            return StreamLookasideCache(self.lookasidehash,
Brian Stinson 3edf28
                                        self.lookaside,
Brian Stinson 3edf28
                                        self.lookaside_cgi,
Brian Stinson 3edf28
                                        )
Brian Stinson 3edf28
        else:
Brian Stinson 3edf28
            return SIGLookasideCache(self.lookasidehash,
Brian Stinson 6e343c
                                     self.lookaside,
Brian Stinson 6e343c
                                     self.lookaside_cgi,
Brian Stinson 6e343c
                                     self.repo_name,
f5ba26
                                     self.branch_merge,
f5ba26
                                     structure=self.lookaside_structure)
639034
Brian Stinson ca61eb
    # redefined loaders
Brian Stinson ca61eb
    def load_rpmdefines(self):
85a850
        '''
85a850
            Populate rpmdefines based on branch data
85a850
        '''
a1a2e2
a1a2e2
        if not self.distgitdir.centosversion:
a1a2e2
            raise rpkgError('Could not get the OS version from the branch:{0}'.format(self.branch_merge))
a1a2e2
a394b1
        self._distvar = self.distgitdir.centosversion
a394b1
        self._distval = self._distvar.replace('.', '_')
Brian Stinson f12d46
Brian Stinson d6d6d7
        self._disttag = 'el%s' % self._distval
a394b1
        self._rpmdefines = ["--define '_sourcedir %s'" % self.layout.sourcedir,
a394b1
                            "--define '_specdir %s'" % self.layout.specdir,
a394b1
                            "--define '_builddir %s'" % self.layout.builddir,
a394b1
                            "--define '_srcrpmdir %s'" % self.layout.srcrpmdir,
a394b1
                            "--define '_rpmdir %s'" % self.layout.rpmdir,
a394b1
                            "--define 'dist .%s'" % self._disttag,
Brian Stinson ca61eb
                            # int and float this to remove the decimal
a394b1
                            "--define '%s 1'" % self._disttag]
a394b1
        self.log.debug("RPMDefines: %s" % self._rpmdefines)
Brian Stinson ca61eb
James Antill dda40d
    def construct_build_url(self, *args, **kwargs):
James Antill dda40d
        """Override build URL for CentOS/Fedora Koji build
James Antill dda40d
James Antill dda40d
        In CentOS/Fedora Koji, anonymous URL should have prefix "git+https://"
James Antill dda40d
        """
James Antill dda40d
        url = super(Commands, self).construct_build_url(*args, **kwargs)
James Antill dda40d
        return 'git+{0}'.format(url)
James Antill dda40d
Brian Stinson 6ba768
    def load_target(self):
Brian Stinson 6ba768
        """ This sets the target attribute (used for mock and koji) """
Brian Stinson 3f76b3
8b3983
        self._target = self.distgitdir.target