Mercurial > hg > mercurial-source
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: |