1
2
3
4
5
6
7
8
9
10
11
12
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
25 _recipeType = RECIPE_TYPE_FILESET
26 internalAbstractBaseClass = 1
27
28
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 = []):
95
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
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
142
143 - def __init__(self, repos, cfg, label, flavor, extraMacros={},
144 laReposCache = None, srcdirs = None):