Package conary :: Package build :: Module filesetrecipe
[hide private]
[frames] | no frames]

Source Code for Module conary.build.filesetrecipe

  1  # 
  2  # Copyright (c) 2005-2008 rPath, Inc. 
  3  # 
  4  # This program is distributed under the terms of the Common Public License, 
  5  # version 1.0. A copy of this license should have been distributed with this 
  6  # source file in a file called LICENSE. If it is not present, the license 
  7  # is always available at http://www.rpath.com/permanent/licenses/CPL-1.0. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, but 
 10  # without any warranty; without even the implied warranty of merchantability 
 11  # or fitness for a particular purpose. See the Common Public License for 
 12  # full details. 
 13  # 
 14   
 15  from fnmatch import fnmatchcase 
 16  import os 
 17   
 18  from conary.build.recipe import Recipe, RECIPE_TYPE_FILESET 
 19  from conary import errors 
 20  from conary.build import errors as builderrors 
 21  from conary.build import macros 
 22  from conary.lib import util 
 23   
24 -class FilesetRecipe(Recipe):
25 _recipeType = RECIPE_TYPE_FILESET 26 internalAbstractBaseClass = 1 27 28 # XXX need to work on adding files from different flavors of troves
29 - def addFileFromPackage(self, pattern, pkg, recurse, remapList):
30 pathMap = {} 31 for (pathId, pkgPath, fileId, version) in pkg.iterFileList(): 32 pathMap[pkgPath] = (pathId, fileId, version) 33 34 patternList = util.braceExpand(pattern) 35 matches = {} 36 for pattern in patternList: 37 if not recurse: 38 matchList = [ n for n in pathMap.keys() if 39 fnmatchcase(n, pattern)] 40 else: 41 matchList = [] 42 dirCount = pattern.count("/") 43 for n in pathMap.iterkeys(): 44 i = n.count("/") 45 if i > dirCount: 46 dirName = os.sep.join(n.split(os.sep)[:dirCount + 1]) 47 match = fnmatchcase(dirName, pattern) 48 elif i == dirCount: 49 match = fnmatchcase(n, pattern) 50 else: 51 match = False 52 53 if match: matchList.append(n) 54 55 for path in matchList: 56 matches[path] = pathMap[path] 57 58 if not matches: 59 return False 60 61 for path in matches.keys(): 62 (pathId, fileId, version) = matches[path] 63 64 for (old, new) in remapList: 65 if path == old: 66 path = new 67 break 68 elif len(path) > len(old) and path.startswith(old) and \ 69 path[len(old)] == "/": 70 path = new + path[len(old):] 71 break 72 73 if self.paths.has_key(path): 74 raise builderrors.RecipeFileError( 75 "%s has been included multiple times" % path) 76 77 self.files[pathId] = (path, fileId, version) 78 self.paths[path] = 1 79 80 return True
81
82 - def addFile(self, pattern, component, versionStr = None, recurse = True, 83 remap = []):
84 pattern = pattern % self.macros 85 component = component % self.macros 86 if versionStr: 87 versionStr = versionStr % self.macros 88 if remap: 89 if isinstance(remap, tuple): 90 remap = [ remap ] 91 remap = [ (old % self.macros, new % self.macros) 92 for (old,new) in remap ] 93 self.requestedFiles.setdefault( 94 (component, versionStr), []).append((pattern, recurse, remap))
95
96 - def _addFile(self, pkg, itemList):
97 """ 98 Adds files which match pattern from version versionStr of component. 99 Pattern is glob-style, with brace expansion. If recurse is set, 100 anything below a directory which matches pattern is also included, 101 and the directory itself does not have to be part of the trove. 102 Remap is a list of (oldPath, newPath) tuples. The first oldPath 103 which matches the start of a matched pattern is rewritten as 104 newPath. 105 """ 106 107 for (pattern, recurse, remap) in itemList: 108 foundIt = False 109 for sub in self.repos.walkTroveSet(pkg): 110 foundIt = foundIt or self.addFileFromPackage( 111 pattern, sub, recurse, remap) 112 113 if not foundIt: 114 raise builderrors.RecipeFileError( 115 "%s does not exist in version %s of %s" % \ 116 (pattern, pkg.getVersion().asString(), pkg.getName()))
117
118 - def findAllFiles(self):
119 findList = [ (x[0], x[1], None) for x in self.requestedFiles ] 120 try: 121 troveSet = self.repos.findTroves(self.label, findList, 122 defaultFlavor = self.flavor) 123 except errors.TroveNotFound, e: 124 raise builderrors.RecipeFileError, str(e) 125 126 for (component, versionStr), itemList in \ 127 self.requestedFiles.iteritems(): 128 pkgList = troveSet[(component, versionStr, None)] 129 130 if len(pkgList) == 0: 131 raise builderrors.RecipeFileError( 132 "no packages match %s" % component) 133 elif len(pkgList) > 1: 134 raise builderrors.RecipeFileError("too many packages match %s" % component) 135 136 pkg = self.repos.getTrove(*pkgList[0]) 137 self._addFile(pkg, itemList)
138
139 - def iterFileList(self):
140 for (pathId, (path, fileId, version)) in self.files.iteritems(): 141 yield (pathId, path, fileId, version)
142
143 - def __init__(self, repos, cfg, label, flavor, extraMacros={}, 144 laReposCache = None, srcdirs = None):
145 Recipe.