1
2
3
4
5
6
7
8
9
10
11
12
13
14 from conary.deps import deps
15 from conary.repository import changeset
16 from conary import errors
17 from conary import versions
18
21
23 BRANCH_SOURCE = 1 << 0
24 BRANCH_BINARY = 1 << 1
25 BRANCH_ALL = BRANCH_SOURCE | BRANCH_BINARY
26
30 return self._createBranchOrShadow(newLabel, troveList, shadow = False,
31 branchType = branchType,
32 sigKeyId = sigKeyId)
33
37 return self._createBranchOrShadow(newLabel, troveList, shadow = True,
38 branchType = branchType,
39 sigKeyId = sigKeyId)
40
42
43
44 query = {}
45 for trove in troves:
46 versionDict = query.setdefault(trove.getName(), {})
47 b = trove.getVersion().branch().createShadow(newLabel)
48 versionDict[b] = None
49
50 results = self.repos.getTroveLeavesByBranch(query)
51
52 if not results:
53 return []
54
55 oldTroves = []
56 for trove in troves:
57 versionDict = results.get(trove.getName(), {})
58 b = trove.getVersion().branch().createShadow(newLabel)
59 versionList = [ x for x in versionDict if x.branch() == b and not x.isModifiedShadow() ]
60 if not versionList:
61 continue
62 latestVersion = max(versionList)
63 oldVersion = latestVersion.parentVersion()
64
65
66 oldTroves.extend((trove.getName(), oldVersion, x) \
67 for x in versionDict[latestVersion])
68
69 shadowedTroves = self.repos.getTroves(oldTroves, withFiles=False)
70
71 shadowed = {}
72 for shadowedTrove in shadowedTroves:
73 (n,v,f) = shadowedTrove.getNameVersionFlavor()
74 shadowed[n, v.branch(), f] = v
75
76 laterShadows = []
77 for trove in troves:
78 (n,v,f) = trove.getNameVersionFlavor()
79 shadowedVer = shadowed.get((n, v.branch(), f), None)
80 if not shadowedVer:
81 continue
82 if v < shadowedVer:
83
84
85 laterShadows.append((n, v, f, shadowedVer))
86 return laterShadows
87
90 cs = changeset.ChangeSet()
91
92 seen = set(troveList)
93 dupList = []
94 needsCommit = False
95
96 newLabel = versions.Label(newLabel)
97
98 while troveList:
99 leavesByLabelOps = {}
100
101 troves = self.repos.getTroves(troveList)
102 troveList = set()
103 branchedTroves = {}
104
105 if shadow:
106 laterShadows = self._checkForLaterShadows(newLabel, troves)
107
108
109
110 if laterShadows:
111 msg = []
112 for n, v, f, shadowedVer in laterShadows:
113 msg.append('''\
114 Cannot shadow backwards - already shadowed
115 %s=%s[%s]
116 cannot shadow earlier trove
117 %s=%s[%s]
118 ''' % (n, shadowedVer, f, n, v, f))
119 raise BranchError('\n\n'.join(msg))
120
121 for trove in troves:
122 if trove.isRedirect():
123 raise errors.ShadowRedirect(*trove.getNameVersionFlavor())
124
125
126 newTroves = [ x for x in
127 trove.iterTroveList(strongRefs=True,
128 weakRefs=True) if x not in seen ]
129 troveList.update(newTroves)
130 seen.update(newTroves)
131
132 troveName = trove.getName()
133
134 if troveName.endswith(':source'):
135 if not(branchType & self.BRANCH_SOURCE):
136 continue
137
138 elif branchType & self.BRANCH_SOURCE:
139
140
141
142
143
144 if not trove.getSourceName():
145 from conary.lib import log
146 log.warning('%s has no source information' % troveName)
147 sourceName = troveName
148 else:
149 sourceName = trove.getSourceName()
150
151 key = (sourceName,
152 trove.getVersion().getSourceVersion(False),
153 deps.Flavor())
154 if key not in seen:
155 troveList.add(key)
156 seen.add(key)
157
158 if not(branchType & self.BRANCH_BINARY):
159 continue
160
161 if shadow:
162 branchedVersion = trove.getVersion().createShadow(newLabel)
163 else:
164 branchedVersion = trove.getVersion().createBranch(newLabel,
165 withVerRel = 1)
166
167 branchedTrove = trove.copy()
168 branchedTrove.changeVersion(branchedVersion)
169
170 branchedTrove.troveInfo.sigs.reset()
171
172 branchedTrove.copyMetadata(trove)
173
174
175
176 for ((name, version, flavor), byDefault, isStrong) \
177 in trove.iterTroveListInfo():
178 if shadow:
179 branchedVersion = version.createShadow(newLabel)
180 else:
181 branchedVersion = version.createBranch(newLabel,
182 withVerRel = 1)
183 branchedTrove.delTrove(name, version, flavor,
184 missingOkay = False,
185 weakRef=not isStrong)
186 branchedTrove.addTrove(name, branchedVersion, flavor,
187 byDefault=byDefault,
188 weakRef=not isStrong)
189
190 key = (trove.getName(), branchedTrove.getVersion(),
191 trove.getFlavor())
192
193 if sigKeyId is not