# pylint: disable=line-too-long,abstract-class-not-used ''' Top level function library for centpkg ''' # Author(s): # Jesse Keating # Pat Riehecky # Brian Stinson # # This program 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; either version 2 of the License, or (at your # option) any later version. See http://www.gnu.org/copyleft/gpl.html for # the full text of the license. import re import warnings import git from pyrpkg import Commands, rpkgError from pyrpkg.utils import cached_property # doc/centpkg_man_page.py uses the 'cli' import from . import cli # noqa from .lookaside import StreamLookasideCache, SIGLookasideCache _DEFAULT_VERSION = '9' class DistGitDirectory(object): signame = None centosversion = _DEFAULT_VERSION projectname = None releasename = None distrobranch = False repo = None git_origin_substr = 'git@gitlab.com/redhat/centos-stream' def __init__(self, branchtext, repo_path=None): if repo_path: # self.repo = git.cmd.Git(repo_path) self.repo = git.repo.Repo(repo_path) sigtobranchre = r'c(?P\d+[s]?)-sig-(?P\w+)-?(?P\w+)?-?(?P\w+)?' distrobranchre = r'c(?P\d+)-?(?P\w+)?' oldbranchre = r'(?P\w+)(?P\d)' sigmatch = re.match(sigtobranchre, branchtext) distromatch = re.match(distrobranchre, branchtext) oldbranchmatch = re.match(oldbranchre, branchtext) if sigmatch: gd = sigmatch.groupdict() self.signame = gd['signame'] self.centosversion = gd['centosversion'] # Users have the option to specify (or not specify) common in their # git repos. Ww need to handle these cases because common is not a # project nor is it a release. if gd['projectname'] != 'common': self.projectname = gd['projectname'] if gd['releasename'] != 'common': self.releasename = gd['releasename'] elif distromatch: gd = distromatch.groupdict() self.distrobranch = True self.signame = 'centos' self.centosversion = gd['centosversion'] if gd['projectname'] != 'common': self.projectname = gd['projectname'] elif oldbranchmatch: warnings.warn("This branch is deprecated and will be removed soon", DeprecationWarning) else: if not self.is_fork(): raise ValueError("Branchname: {0} is not valid".format(branchtext)) else: self.distrobranch = True self.signame = 'centos' self.projectname = self.get_origin().split('_')[-1].replace('.git', '') warnings.warn('Remote "origin" was detected as a fork, ignoring branch name checking') def get_origin(self): if self.repo is None: return '' if 'origin' not in self.repo.remotes: return '' urls = [u for u in self.repo.remotes['origin'].urls] if len(urls) == 0: return '' return urls[0] def is_fork(self): """ Check if origin remote repository is using a fork url. Returns bool A boolean flag indicating if origin remote url is using a forked repository url. """ # git+ssh://git@gitlab.com/redhat/centos-stream/rpms/binutils.git if self.repo is None: return False return self.git_origin_substr not in self.get_origin() @property def target(self): projectorcommon = self.projectname releaseorcommon = self.releasename if self.distrobranch: if self.centosversion not in ('6', '7'): return 'c{}s-candidate'.format(self.centosversion) else: return '-'.join(filter(None, ['c'+self.centosversion, projectorcommon])) if not releaseorcommon: if not projectorcommon or projectorcommon == 'common': projectorcommon = 'common' else: releaseorcommon = 'common' return '-'.join(filter(None, [self.signame+self.centosversion, projectorcommon, releaseorcommon])) + '-el{0}'.format(self.centosversion) class Commands(Commands): ''' For the pyrpkg commands with centpkg behavior ''' def __init__(self, *args, **kwargs): ''' Init the object and some configuration details. ''' super(Commands, self).__init__(*args, **kwargs) # For MD5 we want to use the old format of source files, the BSD format # should only be used when configured for SHA512 self.source_entry_type = 'bsd' if self.lookasidehash != 'md5' else 'old' self.branchre = 'c\d{1,}(s)?(tream)?|master' @property def distgitdir(self): return DistGitDirectory(self.branch_merge, repo_path=self.path) @cached_property def lookasidecache(self): if self.distgitdir.distrobranch: return StreamLookasideCache(self.lookasidehash, self.lookaside, self.lookaside_cgi, ) else: return SIGLookasideCache(self.lookasidehash, self.lookaside, self.lookaside_cgi, self.repo_name, self.branch_merge) # redefined loaders def load_rpmdefines(self): ''' Populate rpmdefines based on branch data ''' if not self.distgitdir.centosversion: raise rpkgError('Could not get the OS version from the branch:{0}'.format(self.branch_merge)) self._distvar = self.distgitdir.centosversion self._distval = self._distvar.replace('.', '_') self._disttag = 'el%s' % self._distval self._rpmdefines = ["--define '_sourcedir %s'" % self.layout.sourcedir, "--define '_specdir %s'" % self.layout.specdir, "--define '_builddir %s'" % self.layout.builddir, "--define '_srcrpmdir %s'" % self.layout.srcrpmdir, "--define '_rpmdir %s'" % self.layout.rpmdir, "--define 'dist .%s'" % self._disttag, # int and float this to remove the decimal "--define '%s 1'" % self._disttag] self.log.debug("RPMDefines: %s" % self._rpmdefines) def construct_build_url(self, *args, **kwargs): """Override build URL for CentOS/Fedora Koji build In CentOS/Fedora Koji, anonymous URL should have prefix "git+https://" """ url = super(Commands, self).construct_build_url(*args, **kwargs) return 'git+{0}'.format(url) def load_target(self): """ This sets the target attribute (used for mock and koji) """ self._target = self.distgitdir.target