<s> from conary import trove , versions <EOL> from conary . deps import deps <EOL> from conary . build import errors as builderrors <EOL> from conary . build import defaultrecipes <EOL> from conary . build import macros <EOL> from conary . build import use <EOL> from conary . build . recipe import Recipe , RECIPE_TYPE_REDIRECT <EOL> from conary . build . packagerecipe import BaseRequiresRecipe <EOL> from conary . lib import log <EOL> class _Redirect ( object ) : <EOL> __slots__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self ) : <EOL> self . components = [ ] <EOL> def addComponents ( self , nameList ) : <EOL> self . components += nameList <EOL> class _RemoveRedirect ( _Redirect ) : <EOL> isRemove = True <EOL> class _RedirectInfo ( _Redirect ) : <EOL> __slots__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> isRemove = False <EOL> def __init__ ( self , targetName , targetBranch , targetFlavor ) : <EOL> assert ( targetName is not None ) <EOL> _Redirect . __init__ ( self ) <EOL> self . targetName = targetName <EOL> self . targetBranch = targetBranch <EOL> self . targetFlavor = targetFlavor <EOL> class _Redirections ( dict ) : <EOL> def add ( self , sourceName , sourceFlavor , redir ) : <EOL> l = self . setdefault ( ( sourceName , sourceFlavor ) , [ ] ) <EOL> l . append ( redir ) <EOL> class _RedirectRule ( object ) : <EOL> __slots__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def findAvailableTargetFlavors ( self , repos ) : <EOL> if self . branchStr is None : <EOL> return set ( ) <EOL> if self . branchStr [ <NUM_LIT:0> ] == '<STR_LIT:/>' : <EOL> branch = versions . VersionFromString ( self . branchStr ) <EOL> if not isinstance ( branch , versions . Branch ) : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" "<STR_LIT>" <EOL> log . info ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> matches = repos . getTroveLeavesByBranch ( <EOL> { self . destName : { branch : None } } ) <EOL> else : <EOL> label = versions . Label ( self . branchStr ) <EOL> matches = repos . getTroveLatestByLabel ( <EOL> { self . destName : { label : None } } ) <EOL> targetFlavors = set ( ) <EOL> for version , flavorList in matches . get ( self . destName , { } ) . iteritems ( ) : <EOL> targetFlavors . update ( ( version , x ) for x in flavorList ) <EOL> return targetFlavors <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" % ( self . sourceName , self . sourceFlavor , <EOL> self . destName , self . branchStr , self . targetFlavor ) <EOL> def __init__ ( self , sourceName = None , destName = None , branchStr = None , <EOL> sourceFlavor = None , targetFlavor = None , <EOL> skipTargetMatching = None , allowMultipleTargets = False ) : <EOL> self . sourceName = sourceName <EOL> self . destName = destName <EOL> self . branchStr = branchStr <EOL> self . sourceFlavor = sourceFlavor <EOL> self . targetFlavor = targetFlavor <EOL> self . skipTargetMatching = skipTargetMatching <EOL> self . allowMultipleTargets = allowMultipleTargets <EOL> class _RedirectRecipe ( Recipe ) : <EOL> Flags = use . LocalFlags <EOL> _recipeType = RECIPE_TYPE_REDIRECT <EOL> internalAbstractBaseClass = <NUM_LIT:1> <EOL> def _addRule ( self , rule ) : <EOL> l = self . rules . setdefault ( rule . sourceName , list ( ) ) <EOL> if rule . sourceFlavor is None : <EOL> l . append ( rule ) <EOL> else : <EOL> l . insert ( <NUM_LIT:0> , rule ) <EOL> def addRedirect ( self , toTrove , branchStr = None , sourceFlavor = None , <EOL> targetFlavor = None , fromTrove = None , <EOL> skipTargetMatching = False , allowMultipleTargets = False ) : <EOL> if ( ( sourceFlavor is not None ) and ( targetFlavor is None ) ) or ( ( targetFlavor is not None ) and ( sourceFlavor is None ) ) : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" <EOL> if sourceFlavor is not None : <EOL> f = deps . parseFlavor ( sourceFlavor ) <EOL> if f is None : <EOL> raise ValueError , '<STR_LIT>' % sourceFlavor <EOL> sourceFlavor = f <EOL> if targetFlavor is not None : <EOL> f = deps . parseFlavor ( targetFlavor ) <EOL> if f is None : <EOL> raise ValueError , '<STR_LIT>' % targetFlavor <EOL> targetFlavor = f <EOL> if fromTrove is None : <EOL> fromTrove = self . name <EOL> elif fromTrove . find ( "<STR_LIT::>" ) != - <NUM_LIT:1> : <EOL> raise ValueError , '<STR_LIT>' <EOL> rule = _RedirectRule ( sourceName = fromTrove , destName = toTrove , <EOL> branchStr = branchStr , sourceFlavor = sourceFlavor , <EOL> targetFlavor = targetFlavor , <EOL> skipTargetMatching = skipTargetMatching , <EOL> allowMultipleTargets = allowMultipleTargets ) <EOL> self . _addRule ( rule ) <EOL> def addRemoveRedirect ( self , fromTrove = None ) : <EOL> if fromTrove is None : <EOL> fromTrove = self . name <EOL> elif fromTrove . find ( "<STR_LIT::>" ) != - <NUM_LIT:1> : <EOL> raise ValueError , '<STR_LIT>' <EOL> rule = _RedirectRule ( sourceName = fromTrove ) <EOL> self . _addRule ( rule ) <EOL> def _findSourceTroves ( self ) : <EOL> sourceSearch = { } <EOL> for fromTrove in self . rules . iterkeys ( ) : <EOL> sourceSearch . setdefault ( fromTrove , { self . branch : None } ) <EOL> sourceTroveMatches = self . repos . getTroveLeavesByBranch ( sourceSearch ) <EOL> if len ( sourceTroveMatches ) != len ( sourceSearch ) : <EOL> missing = set ( sourceSearch ) - set ( sourceTroveMatches ) <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" % "<STR_LIT:U+0020>" . join ( missing ) <EOL> return sourceTroveMatches <EOL> def _getSourceTroves ( self , searchResult ) : <EOL> l = [ ] <EOL> for name , d in searchResult . iteritems ( ) : <EOL> for version , flavorList in d . iteritems ( ) : <EOL> l += [ ( name , ( None , None ) , ( version , x ) , True ) <EOL> for x in flavorList ] <EOL> trvCsDict = { } <EOL> cs = self . repos . createChangeSet ( l , recurse = False , <EOL> withFiles = False ) <EOL> for trvCs in cs . iterNewTroveList ( ) : <EOL> info = ( trvCs . getName ( ) , trvCs . getNewVersion ( ) , <EOL> trvCs . getNewFlavor ( ) ) <EOL> trvCsDict [ info ] = trvCs <EOL> return trvCsDict <EOL> @ staticmethod <EOL> def _getTargetRules ( rules , name ) : <EOL> targetRules = rules . get ( name , None ) <EOL> if targetRules is None : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" % name <EOL> return targetRules <EOL> def _buildRedirect ( self , trvCsDict , sourceFlavor , <EOL> sourceVersion , rule , target ) : <EOL> if target [ <NUM_LIT:0> ] is not None : <EOL> redirInfo = _RedirectInfo ( target [ <NUM_LIT:0> ] , target [ <NUM_LIT:1> ] . branch ( ) , rule . targetFlavor ) <EOL> else : <EOL> redirInfo = _RemoveRedirect ( ) <EOL> self . redirections . add ( rule . sourceName , sourceFlavor , redirInfo ) <EOL> if ( trove . troveIsGroup ( rule . sourceName ) or <EOL> not trove . troveIsCollection ( rule . sourceName ) ) : <EOL> return <EOL> if target [ <NUM_LIT:0> ] is not None : <EOL> targetTrove = self . repos . getTrove ( withFiles = False , * target ) <EOL> targetComponents = set ( [ x [ <NUM_LIT:0> ] . split ( '<STR_LIT::>' ) [ <NUM_LIT:1> ] <EOL> for x in <EOL> targetTrove . iterTroveList ( strongRefs = True ) ] ) <EOL> else : <EOL> targetComponents = set ( ) <EOL> trvCs = trvCsDict [ ( rule . sourceName , sourceVersion , sourceFlavor ) ] <EOL> trv = trove . Trove ( trvCs ) <EOL> currentComponents = set ( [ x [ <NUM_LIT:0> ] . split ( '<STR_LIT::>' ) [ <NUM_LIT:1> ] for x in <EOL> trv . iterTroveList ( strongRefs = True ) ] ) <EOL> for compName in currentComponents & targetComponents : <EOL> sourceCompName = rule . sourceName + '<STR_LIT::>' + compName <EOL> targetCompName = redirInfo . targetName + '<STR_LIT::>' + compName <EOL> self . redirections . add ( sourceCompName , sourceFlavor , <EOL> _RedirectInfo ( targetCompName , redirInfo . targetBranch , <EOL> redirInfo . targetFlavor ) ) <EOL> allVersions = self . repos . getTroveVersionsByBranch ( <EOL> { trv . getName ( ) : <EOL> { trv . getVersion ( ) . branch ( ) : None } } ) <EOL> l = [ ] <EOL> for subVersion , subFlavorList in allVersions [ trv . getName ( ) ] . iteritems ( ) : <EOL> l += [ ( trv . getName ( ) , subVersion , flavor ) <EOL> for flavor in subFlavorList ] <EOL> allTroves = self . repos . getTroves ( l , withFiles = False ) <EOL> allComponents = set ( ) <EOL> for otherTrv in allTroves : <EOL> allComponents . update ( <EOL> [ x [ <NUM_LIT:0> ] . split ( '<STR_LIT::>' ) [ <NUM_LIT:1> ] for x in <EOL> otherTrv . iterTroveList ( strongRefs = True ) ] ) <EOL> for subName in allComponents - targetComponents : <EOL> newName = rule . sourceName + '<STR_LIT::>' + subName <EOL> self . redirections . add ( newName , sourceFlavor , _RemoveRedirect ( ) ) <EOL> redirInfo . addComponents ( <EOL> [ rule . sourceName + '<STR_LIT::>' + x for x in allComponents ] ) <EOL> def findTroves ( self ) : <EOL> sourceTroveMatches = self . _findSourceTroves ( ) <EOL> trvCsDict = self . _getSourceTroves ( sourceTroveMatches ) <EOL> redirRuleMap = { } <EOL> for sourceName , sourceTroveVersions in sourceTroveMatches . iteritems ( ) : <EOL> targetRules = self . _getTargetRules ( self . rules , sourceName ) <EOL> additionalNames = set ( ) <EOL> for rule in targetRules : <EOL> targetFlavors = rule . findAvailableTargetFlavors ( self . repos ) <EOL> if rule . branchStr and not targetFlavors : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" % ( rule . destName ) <EOL> foundMatch = False <EOL> for sourceVersion , flavorList in sourceTroveVersions . items ( ) : <EOL> for sourceFlavor in flavorList : <EOL> if rule . sourceFlavor is not None and sourceFlavor != rule . sourceFlavor : <EOL> continue <EOL> match = None <EOL> for targetVersion , targetFlavor in targetFlavors : <EOL> if ( not rule . skipTargetMatching and <EOL> rule . targetFlavor is not None and <EOL> targetFlavor != rule . targetFlavor ) : <EOL> continue <EOL> if ( ( rule . sourceFlavor is not None ) <EOL> or rule . skipTargetMatching <EOL> or sourceFlavor . score ( targetFlavor ) is not False ) : <EOL> match = ( targetVersion , targetFlavor ) <EOL> break <EOL> if match is not None : <EOL> if ( sourceName , sourceFlavor ) in self . redirections : <EOL> previousRule = redirRuleMap [ ( sourceName , <EOL> sourceFlavor ) ] <EOL> if ( previousRule . sourceFlavor <EOL> is not None and <EOL> rule . sourceFlavor is None ) : <EOL> continue <EOL> if not rule . allowMultipleTargets : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" "<STR_LIT>" % ( sourceName , sourceFlavor ) <EOL> targetTroveInfo = ( rule . destName , match [ <NUM_LIT:0> ] , <EOL> match [ <NUM_LIT:1> ] ) <EOL> elif not targetFlavors : <EOL> targetTroveInfo = ( None , None , None ) <EOL> elif rule . targetFlavor is not None : <EOL> raise builderrors . RecipeFileError , "<STR_LIT>" % ( sourceName , targetFlavor ) <EOL> else : <EOL> continue <EOL> foundMatch = True <EOL> redirRuleMap [ ( sourceName , sourceFlavor ) ] = rule <EOL> self . _buildRedirect ( trvCsDict , sourceFlavor , <EOL> sourceVersion , rule , <EOL> targetTroveInfo ) <EOL> if not foundMatch : <EOL> raise builderrors . CookError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % sourceName ) <EOL> def getRedirections ( self ) : <EOL> return self . redirections <EOL> def __init__ ( self , repos , cfg , branch , flavor , extraMacros = { } ) : <EOL> Recipe . __init__ ( self , cfg ) <EOL> self . repos = repos <EOL> self . redirections = _Redirections ( ) <EOL> self . flavor = flavor <EOL> if branch is not None : <EOL> self . macros . binarybranch = str ( branch ) <EOL> self . macros . update ( extraMacros ) <EOL> self . branch = versions . VersionFromString ( self . macros . binarybranch ) <EOL> else : <EOL> self . branch = None <EOL> self . rules = { } <EOL> exec defaultrecipes . RedirectRecipe </s>
