comparison mercurial/transaction.py @ 22078:feb4797c676e

transaction: add a file generation mechanism A new `transaction.addfilegenerator` function is added. It allows external code to register files to be generated. See inline documentation for details. It is important to gather all file creation logic on the transaction as at some point we'll want to mimic the "pre-transaction-commit" logic that we use for revlog. I'm refering to the logic that lets hooks see the result of the transaction before it actually gets committed.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 07 Aug 2014 14:40:02 -0700
parents 2990ce46fc2d
children b3e51675f98e
comparison
equal deleted inserted replaced
22077:2990ce46fc2d 22078:feb4797c676e
94 self.backupsfile = opener.open(self.backupjournal, 'w') 94 self.backupsfile = opener.open(self.backupjournal, 'w')
95 if createmode is not None: 95 if createmode is not None:
96 opener.chmod(self.journal, createmode & 0666) 96 opener.chmod(self.journal, createmode & 0666)
97 opener.chmod(self.backupjournal, createmode & 0666) 97 opener.chmod(self.backupjournal, createmode & 0666)
98 98
99 # hold file generations to be performed on commit
100 self._filegenerators = {}
101
99 def __del__(self): 102 def __del__(self):
100 if self.journal: 103 if self.journal:
101 self._abort() 104 self._abort()
102 105
103 @active 106 @active
171 self.backupmap[file] = len(self.backupentries) - 1 174 self.backupmap[file] = len(self.backupentries) - 1
172 self.backupsfile.write("%s\0%s\0" % (file, backupfile)) 175 self.backupsfile.write("%s\0%s\0" % (file, backupfile))
173 self.backupsfile.flush() 176 self.backupsfile.flush()
174 177
175 @active 178 @active
179 def addfilegenerator(self, genid, filenames, genfunc, order=0):
180 """add a function to generates some files at transaction commit
181
182 The `genfunc` argument is a function capable of generating proper
183 content of each entry in the `filename` tuple.
184
185 At transaction close time, `genfunc` will be called with one file
186 object argument per entries in `filenames`.
187
188 The transaction itself is responsible for the backup, creation and
189 final write of such file.
190
191 The `genid` argument is used to ensure the same set of file is only
192 generated once. Call to `addfilegenerator` for a `genid` already
193 present will overwrite the old entry.
194
195 The `order` argument may be used to control the order in which multiple
196 generator will be executed.
197 """
198 self._filegenerators[genid] = (order, filenames, genfunc)
199
200 @active
176 def find(self, file): 201 def find(self, file):
177 if file in self.map: 202 if file in self.map:
178 return self.entries[self.map[file]] 203 return self.entries[self.map[file]]
179 if file in self.backupmap: 204 if file in self.backupmap:
180 return self.backupentries[self.backupmap[file]] 205 return self.backupentries[self.backupmap[file]]
211 return self.count > 0 236 return self.count > 0
212 237
213 @active 238 @active
214 def close(self): 239 def close(self):
215 '''commit the transaction''' 240 '''commit the transaction'''
241 # write files registered for generation
242 for order, filenames, genfunc in sorted(self._filegenerators.values()):
243 files = []
244 try:
245 for name in filenames:
246 self.addbackup(name)
247 files.append(self.opener(name, 'w', atomictemp=True))
248 genfunc(*files)
249 finally:
250 for f in files:
251 f.close()
252
216 if self.count == 1 and self.onclose is not None: 253 if self.count == 1 and self.onclose is not None:
217 self.onclose() 254 self.onclose()
218 255
219 self.count -= 1 256 self.count -= 1
220 if self.count != 0: 257 if self.count != 0: