2820c61a |
import os |
87815216 |
import queue |
45c9260c |
import json
import operator |
87815216 |
from distutils.version import StrictVersion
from Logger import Logger |
45c9260c |
from constants import constants |
f93ef2b0 |
from StringUtils import StringUtils
from distutils.version import LooseVersion |
4ed339b4 |
from SpecParser import SpecParser |
accc8120 |
|
4ed339b4 |
class SpecData(object):
|
a007b861 |
def __init__(self, arch, logPath, specFilesPath):
self.arch = arch |
4ed339b4 |
self.logger = Logger.getLogger("SpecData", logPath, constants.logLevel)
# map default package name to list of SpecObjects. Usually it is just
# a list with only one element. But, for multiversion spec file this
# list has as many elements as many versions of given package name
# are available |
5d822c2d |
self.mapSpecObjects = {} |
4ed339b4 |
# map subpackage names to default package name |
87815216 |
self.mapPackageToSpec = {} |
4ed339b4 |
# map spec file name to SpecObject |
cfd85ba2 |
self.mapSpecFileNameToSpecObj = {} |
5062126c |
|
4ed339b4 |
self._readSpecs(specFilesPath)
|
ed27cf29 |
|
4ed339b4 |
# Read all .spec files from the given folder including subfolders,
# creates corresponding SpecObjects and put them in internal mappings.
def _readSpecs(self, specFilesPath):
for specFile in self._getListSpecFiles(specFilesPath): |
a007b861 |
spec = SpecParser(specFile, self.arch) |
4ed339b4 |
# skip the specfile if buildarch differs
buildarch = spec.packages.get('default').buildarch
if (buildarch != "noarch" and |
a007b861 |
buildarch != self.arch): |
ed27cf29 |
self.logger.info("skipping spec file: "+str(specFile))
continue
|
4ed339b4 |
specObj = spec.createSpecObject()
name = specObj.name |
2820c61a |
for specPkg in specObj.listPackages: |
4ed339b4 |
self.mapPackageToSpec[specPkg] = name
if name in self.mapSpecObjects:
self.mapSpecObjects[name].append(specObj) |
5d822c2d |
else: |
4ed339b4 |
self.mapSpecObjects[name]=[specObj]
|
cfd85ba2 |
self.mapSpecFileNameToSpecObj[os.path.basename(specFile)]=specObj |
ed27cf29 |
|
4ed339b4 |
# Sort the multiversion list to make getHighestVersion happy |
5d822c2d |
for key, value in self.mapSpecObjects.items():
if len(value) > 1:
self.mapSpecObjects[key] = sorted(value,
key=lambda x : self.compareVersions(x),
reverse=True) |
5062126c |
|
4ed339b4 |
def _getListSpecFiles(self, path):
listSpecFiles = [] |
2820c61a |
for dirEntry in os.listdir(path):
dirEntryPath = os.path.join(path, dirEntry) |
87815216 |
if (os.path.isfile(dirEntryPath) and |
ed27cf29 |
dirEntryPath.endswith(".spec")): |
2820c61a |
listSpecFiles.append(dirEntryPath)
elif os.path.isdir(dirEntryPath): |
4ed339b4 |
listSpecFiles.extend(self._getListSpecFiles(dirEntryPath))
return listSpecFiles |
5062126c |
|
f93ef2b0 |
def _getProperVersion(self,depPkg):
if (depPkg.compare == ""):
return self.getHighestVersion(depPkg.package) |
4ed339b4 |
specObjs=self.getSpecObjects(depPkg.package) |
cfd85ba2 |
try:
for obj in specObjs: |
f93ef2b0 |
verrel=obj.version+"-"+obj.release
if depPkg.compare == ">=": |
cfd85ba2 |
if LooseVersion(verrel) >= LooseVersion(depPkg.version):
return obj.version |
f93ef2b0 |
elif depPkg.compare == "<=": |
cfd85ba2 |
if LooseVersion(verrel) <= LooseVersion(depPkg.version):
return obj.version |
f93ef2b0 |
elif depPkg.compare == "=": |
cfd85ba2 |
if LooseVersion(verrel) == LooseVersion(depPkg.version):
return obj.version
if LooseVersion(obj.version) == LooseVersion(depPkg.version):
return obj.version |
f93ef2b0 |
elif depPkg.compare == "<": |
cfd85ba2 |
if LooseVersion(verrel) < LooseVersion(depPkg.version):
return obj.version |
f93ef2b0 |
elif depPkg.compare == ">": |
cfd85ba2 |
if LooseVersion(verrel) > LooseVersion(depPkg.version):
return obj.version
except Exception as e: |
f8f09a53 |
self.logger.error("Exception happened while searching for: " + \
depPkg.package + depPkg.compare + depPkg.version) |
cfd85ba2 |
raise e |
f93ef2b0 |
# about to throw exception
availableVersions=""
for obj in specObjs:
availableVersions+=" "+obj.name+"-"+obj.version+"-"+obj.release |
f8f09a53 |
raise Exception("Could not find package: " + depPkg.package + \
depPkg.compare + depPkg.version + \
" available specs:" + availableVersions) |
f93ef2b0 |
def _getSpecObjField(self, package, version, field): |
4ed339b4 |
for specObj in self.getSpecObjects(package): |
f93ef2b0 |
if specObj.version == version:
return field(specObj) |
f8f09a53 |
self.logger.error("Could not find " + package + |
f93ef2b0 |
"-" + version + " package from specs")
raise Exception("Invalid package: " + package + "-" + version)
def getBuildRequiresForPackage(self, package, version):
buildRequiresList=[] |
4ed339b4 |
for pkg in self._getSpecObjField(package, version, field=lambda x : x.buildRequires): |
f93ef2b0 |
properVersion = self._getProperVersion(pkg)
buildRequiresList.append(pkg.package+"-"+properVersion)
return buildRequiresList
|
8f56b626 |
def getExtraBuildRequiresForPackage(self, package, version):
packages=[]
for pkg in self._getSpecObjField(package, version, field=lambda x : x.extraBuildRequires):
# no version deps for publishrpms - use just name
packages.append(pkg.package)
return packages
|
a007b861 |
def getBuildRequiresNativeForPackage(self, package, version):
packages=[]
for pkg in self._getSpecObjField(package, version, field=lambda x : x.buildRequiresNative):
properVersion = self._getProperVersion(pkg)
packages.append(pkg.package+"-"+properVersion)
return packages
|
f93ef2b0 |
def getBuildRequiresForPkg(self, pkg):
package, version = StringUtils.splitPackageNameAndVersion(pkg)
return self.getBuildRequiresForPackage(package, version)
# Returns list of [ "pkg1-vers1", "pkg2-vers2",.. ]
def getRequiresAllForPackage(self, package, version):
requiresList=[] |
4ed339b4 |
for pkg in self._getSpecObjField(package, version, field=lambda x : x.installRequires): |
f93ef2b0 |
properVersion = self._getProperVersion(pkg)
requiresList.append(pkg.package+"-"+properVersion)
return requiresList
def getRequiresAllForPkg(self, pkg):
package, version = StringUtils.splitPackageNameAndVersion(pkg)
return self.getRequiresAllForPackage(package, version)
def getRequiresForPackage(self, package, version):
requiresList=[] |
4ed339b4 |
for specObj in self.getSpecObjects(package): |
f93ef2b0 |
if specObj.version == version:
if package in specObj.installRequiresPackages:
requiresPackages = specObj.installRequiresPackages[package]
for pkg in requiresPackages:
properVersion = self._getProperVersion(pkg)
requiresList.append(pkg.package+"-"+properVersion)
return requiresList |
f8f09a53 |
self.logger.error("Could not find " + package + |
f93ef2b0 |
"-" + version + " package from specs")
raise Exception("Invalid package: " + package + "-" + version)
def getRequiresForPkg(self, pkg):
package, version = StringUtils.splitPackageNameAndVersion(pkg)
return self.getRequiresForPackage(package, version)
def getCheckBuildRequiresForPackage(self, package, version):
checkBuildRequiresList=[] |
4ed339b4 |
checkBuildRequiresPackages = self._getSpecObjField(package, version, field=lambda x : x.checkBuildRequires) |
f93ef2b0 |
for pkg in checkBuildRequiresPackages:
properVersion = self._getProperVersion(pkg)
checkBuildRequiresList.append(pkg.package+"-"+properVersion)
return checkBuildRequiresList |
5f40784b |
|
4ed339b4 |
# Returns list of SpecObjects for given subpackage name
def getSpecObjects(self, package): |
4a93976f |
specName=self.getSpecName(package)
return self.mapSpecObjects[specName]
|
e45f5730 |
def getPkgNamesFromObj(self, objlist):
listPkgName=[] |
f93ef2b0 |
for name in objlist: |
e45f5730 |
listPkgName.append(name.package)
return listPkgName
|
f93ef2b0 |
def getRelease(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.release) |
5062126c |
|
f93ef2b0 |
def getVersions(self, package):
versions=[] |
4ed339b4 |
for specObj in self.getSpecObjects(package): |
f93ef2b0 |
versions.append(specObj.version)
return versions |
5062126c |
|
f93ef2b0 |
def getHighestVersion(self, package): |
4ed339b4 |
return self.getSpecObjects(package)[0].version |
5062126c |
|
f93ef2b0 |
def getBuildArch(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.buildarch[package]) |
3cc43c92 |
|
f93ef2b0 |
def getSpecFile(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.specFile) |
5062126c |
|
f93ef2b0 |
def getPatches(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.listPatches) |
3cc43c92 |
|
f93ef2b0 |
def getSources(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.listSources) |
37022ec3 |
|
f93ef2b0 |
def getSHA1(self, package, version, source):
return self._getSpecObjField(package, version, field=lambda x : x.checksums.get(source))
# returns list of package names (no versions)
def getPackages(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.listPackages)
def getPackagesForPkg(self, pkg): |
29d834bc |
pkgs=[] |
f93ef2b0 |
package, version = StringUtils.splitPackageNameAndVersion(pkg) |
29d834bc |
for p in self.getPackages(package, version):
pkgs.append(p+"-"+version)
return pkgs |
f93ef2b0 |
def getRPMPackages(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.listRPMPackages) |
adf248d5 |
|
accc8120 |
@staticmethod |
5d822c2d |
def compareVersions(p):
return (StrictVersion(p.version)) |
87815216 |
def getSpecName(self, package):
if package in self.mapPackageToSpec:
specName = self.mapPackageToSpec[package] |
5d822c2d |
if specName in self.mapSpecObjects: |
51e6babb |
return specName |
26b55679 |
self.logger.error("Could not find " + package + " package from specs") |
87815216 |
raise Exception("Invalid package:" + package) |
b5e09fac |
|
87815216 |
def isRPMPackage(self, package):
if package in self.mapPackageToSpec:
specName = self.mapPackageToSpec[package] |
5d822c2d |
if specName in self.mapSpecObjects: |
af3575c9 |
return True
return False |
b5e09fac |
|
f93ef2b0 |
def getSecurityHardeningOption(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.securityHardening) |
cb4e8710 |
|
f93ef2b0 |
def isCheckAvailable(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.isCheckAvailable) |
b5e09fac |
|
97a9151c |
def getListPackages(self): |
5d822c2d |
return list(self.mapSpecObjects.keys()) |
5062126c |
|
f93ef2b0 |
def getURL(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.url) |
5062126c |
|
f93ef2b0 |
def getSourceURL(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.sourceurl) |
5062126c |
|
f93ef2b0 |
def getLicense(self, package, version):
return self._getSpecObjField(package, version, field=lambda x : x.license)
# Converts "glibc-devel-2.28" into "glibc-2.28"
def getBasePkg(self, pkg):
package, version = StringUtils.splitPackageNameAndVersion(pkg)
return self.getSpecName(package)+"-"+version |
5d822c2d |
|
5062126c |
|
2820c61a |
def printAllObjects(self): |
5d822c2d |
listSpecs = self.mapSpecObjects.keys() |
2820c61a |
for spec in listSpecs: |
cfd85ba2 |
for specObj in self.mapSpecObjects[spec]: |
26b55679 |
self.logger.debug("-----------Spec:"+specObj.name+"--------------")
self.logger.debug("Version:"+specObj.version)
self.logger.debug("Release:"+specObj.release)
self.logger.debug("SpecFile:"+specObj.specFile)
self.logger.debug("Source Files")
self.logger.debug(specObj.listSources)
self.logger.debug("Patch Files")
self.logger.debug(specObj.listPatches)
self.logger.debug("List RPM packages")
self.logger.debug(specObj.listPackages)
self.logger.debug("Build require packages") |
4ed339b4 |
self.logger.debug(self.getPkgNamesFromObj(specObj.buildRequires)) |
26b55679 |
self.logger.debug("install require packages") |
4ed339b4 |
self.logger.debug(self.getPkgNamesFromObj(specObj.installRequires)) |
26b55679 |
self.logger.debug(specObj.installRequiresPackages)
self.logger.debug("security_hardening: " + specObj.securityHardening) |
a007b861 |
self.logger.debug("BuildArch: " + str(specObj.buildarch)) |
26b55679 |
self.logger.debug("------------------------------------------------") |
5e29a499 |
|
accc8120 |
|
45c9260c |
class SPECS(object):
__instance = None |
a007b861 |
specData = {} |
45c9260c |
@staticmethod |
a007b861 |
def getData(arch=None):
if not arch:
arch=constants.currentArch
|
45c9260c |
""" Static access method. """ |
87815216 |
if SPECS.__instance is None: |
45c9260c |
SPECS() |
a007b861 |
return SPECS.__instance.specData[arch] |
45c9260c |
def __init__(self):
""" Virtually private constructor. """ |
87815216 |
if SPECS.__instance is not None: |
45c9260c |
raise Exception("This class is a singleton!")
else:
SPECS.__instance = self
self.initialize()
def initialize(self): |
343d89e8 |
# Preparse some files |
a0abf4dd |
|
accc8120 |
# adding kernelversion rpm macro |
a007b861 |
spec = SpecParser(constants.specPath + "/linux/linux.spec", constants.buildArch) |
4ed339b4 |
defPkg = spec.packages.get('default')
kernelversion = defPkg.version |
87815216 |
constants.addMacro("KERNEL_VERSION", kernelversion) |
45c9260c |
|
accc8120 |
# adding kernelrelease rpm macro |
4ed339b4 |
kernelrelease = defPkg.release |
87815216 |
constants.addMacro("KERNEL_RELEASE", kernelrelease) |
45c9260c |
|
accc8120 |
# adding kernelsubrelease rpm macro |
87815216 |
a, b, c = kernelversion.split(".")
kernelsubrelease = ('%02d%02d%03d%03d' % (int(a),
int(b), int(c),
int(kernelrelease.split('.')[0]))) |
45c9260c |
if kernelsubrelease: |
87815216 |
kernelsubrelease = "." + kernelsubrelease
constants.addMacro("kernelsubrelease", kernelsubrelease) |
45c9260c |
|
343d89e8 |
# Full parsing |
a007b861 |
self.specData[constants.buildArch] = SpecData(constants.buildArch,
constants.logPath,
constants.specPath)
if constants.buildArch != constants.targetArch:
self.specData[constants.targetArch] = SpecData(constants.targetArch,
constants.logPath,
constants.specPath) |