Mercurial > hg
changeset 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 | 5dcc58649b1a |
files | mercurial/transaction.py |
diffstat | 1 files changed, 37 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/transaction.py Thu Aug 07 10:54:17 2014 -0700 +++ b/mercurial/transaction.py Thu Aug 07 14:40:02 2014 -0700 @@ -96,6 +96,9 @@ opener.chmod(self.journal, createmode & 0666) opener.chmod(self.backupjournal, createmode & 0666) + # hold file generations to be performed on commit + self._filegenerators = {} + def __del__(self): if self.journal: self._abort() @@ -173,6 +176,28 @@ self.backupsfile.flush() @active + def addfilegenerator(self, genid, filenames, genfunc, order=0): + """add a function to generates some files at transaction commit + + The `genfunc` argument is a function capable of generating proper + content of each entry in the `filename` tuple. + + At transaction close time, `genfunc` will be called with one file + object argument per entries in `filenames`. + + The transaction itself is responsible for the backup, creation and + final write of such file. + + The `genid` argument is used to ensure the same set of file is only + generated once. Call to `addfilegenerator` for a `genid` already + present will overwrite the old entry. + + The `order` argument may be used to control the order in which multiple + generator will be executed. + """ + self._filegenerators[genid] = (order, filenames, genfunc) + + @active def find(self, file): if file in self.map: return self.entries[self.map[file]] @@ -213,6 +238,18 @@ @active def close(self): '''commit the transaction''' + # write files registered for generation + for order, filenames, genfunc in sorted(self._filegenerators.values()): + files = [] + try: + for name in filenames: + self.addbackup(name) + files.append(self.opener(name, 'w', atomictemp=True)) + genfunc(*files) + finally: + for f in files: + f.close() + if self.count == 1 and self.onclose is not None: self.onclose()