# pylint: disable=line-too-long,abstract-class-not-used
"""
Top level function library for centpkg
"""
# Author(s):
# Jesse Keating <jkeating@redhat.com>
# Pat Riehecky <riehecky@fnal.gov>
# Brian Stinson <bstinson@ksu.edu>
#
# 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, CLLookasideCache
_DEFAULT_VERSION = "9"
class DistGitDirectory(object):
signame = None
centosversion = _DEFAULT_VERSION
projectname = None
releasename = None
distrobranch = False
sigbranch = 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)
rhelbranchre = r"rhel-(?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<appstream>\d+))?"
sigtobranchre = r"c(?P<centosversion>\d+[s]?)-sig-(?P<signame>\w+)-?(?P<projectname>\w+)?-?(?P<releasename>\w+)?"
distrobranchre = r"c(?P<centosversion>\d+)-?(?P<projectname>\w+)?"
javabranchre = r"openjdk-portable-centos-(?P<centosversion>\d+)"
oldbranchre = r"(?P<signame>\w+)(?P<centosversion>\d)"
rhelmatch = re.search(rhelbranchre, branchtext)
sigmatch = re.match(sigtobranchre, branchtext)
distromatch = re.match(distrobranchre, branchtext)
javamatch = re.match(javabranchre, branchtext)
oldbranchmatch = re.match(oldbranchre, branchtext)
if rhelmatch:
gd = rhelmatch.groupdict()
self.distrobranch = True
self.signame = "centos"
self.centosversion = gd["major"]
elif sigmatch:
gd = sigmatch.groupdict()
self.sigbranch = True
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 javamatch:
gd = javamatch.groupdict()
self.distrobranch = True
self.signame = "centos"
self.centosversion = gd["centosversion"]
elif oldbranchmatch:
warnings.warn(
"This branch is deprecated and will be removed soon", DeprecationWarning
)
else:
if not self.is_fork():
warnings.warn(
"Unable to determine if this is a fork or not. Proceeding, but you should double check."
)
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.layout.sources_file_template == "sources":
return StreamLookasideCache(
self.lookasidehash,
self.lookaside,
self.lookaside_cgi,
)
else:
if self.distgitdir.sigbranch:
return SIGLookasideCache(
self.lookasidehash,
self.lookaside,
self.lookaside_cgi,
self.repo_name,
self.branch_merge,
)
else:
return CLLookasideCache(
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._distunset = 'fedora'
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,
# This is so the rhel macro is set for spec files
"--define",
"rhel %s" % self._distval.split("_")[0],
# This is so the centos macro is set for spec files
"--define",
"centos %s" % self._distval.split("_")[0],
# This is so the fedora macro is unset for spec files
"--eval",
"%%undefine %s" % self._distunset,
]
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