1# -*- coding: utf-8 -*- 2# 3# Copyright 2013 Ingo Weinhold 4# Distributed under the terms of the MIT License. 5 6# -- Modules ------------------------------------------------------------------ 7 8import os 9from subprocess import CalledProcessError 10 11from .PackageInfo import PackageInfo, Resolvable, ResolvableExpression 12from .ProvidesManager import ProvidesManager 13from .Utils import sysExit 14 15# -- ProvidesInfo class ------------------------------------------------------- 16 17class ProvidesInfo(Resolvable): 18 def __init__(self, package, providesString): 19 super(ProvidesInfo, self).__init__(providesString) 20 self.package = package 21 22# -- RequiresUpdater class ---------------------------------------------------- 23 24class RequiresUpdater(object): 25 def __init__(self, portPackages, requiredPackages): 26 self._providesManager = ProvidesManager() 27 28 # get the provides for the port packages 29 for package in portPackages: 30 self._providesManager.addProvidesFromPackage(package) 31 32 # get the provides for the required packages 33 for package in requiredPackages: 34 if package.endswith('.hpkg'): 35 self.addPackageFile(package) 36 37 def addPackageFile(self, package): 38 try: 39 packageInfo = PackageInfo(package) 40 except CalledProcessError: 41 sysExit('failed to get provides for package "%s"' % package) 42 43 self._providesManager.addProvidesFromPackageInfo(packageInfo) 44 45 def addPackages(self, directory): 46 for package in os.listdir(directory): 47 if package.endswith('.hpkg') or package.endswith('.PackageInfo'): 48 self.addPackageFile(directory + '/' + package) 49 50 def updateRequiresList(self, requiresList): 51 result = [] 52 for requires in requiresList: 53 requires = requires.strip() 54 if not requires.startswith('#'): 55 result.append(self._updateRequires(requires)) 56 return result 57 58 def getMatchingProvides(self, resolvableExpression): 59 return self._providesManager.getMatchingProvides(resolvableExpression) 60 61 def _updateRequires(self, requires): 62 # split the requires string 63 requires = requires.strip() 64 partialRequires = requires 65 isBase = requires.endswith('base') 66 if isBase: 67 partialRequires = requires[:-4].rstrip() 68 69 resolvableExpression = ResolvableExpression(partialRequires) 70 name = resolvableExpression.name 71 operator = resolvableExpression.operator 72 73 # check whether there's a matching provides and, if so, replace the 74 # given requires 75 matchingProvides = self.getMatchingProvides(resolvableExpression) 76 if not matchingProvides: 77 if self.getMatchingProvides(ResolvableExpression(name)): 78 sysExit('found provides for "%s", but none matching the ' 79 'version requirement' % requires) 80 return requires 81 82 if not matchingProvides.version: 83 return requires 84 if operator in ['<', '<=', '!=']: 85 return requires 86 87 # Enforce the minimum found version, if the requires has no version 88 # requirement or also a minimum. Otherwise enforce the exact version 89 # found. 90 resultOperator = '>=' if operator in [None, '> ', '>='] else '==' 91 result = '%s %s %s' \ 92 % (matchingProvides.name, resultOperator, matchingProvides.version) 93 if isBase: 94 result += ' base' 95 return result 96