Patchwork [4,of,5,main-line-of-work] transaction: support cache for file generator

login
register
mail settings
Submitter Pierre-Yves David
Date Nov. 20, 2014, 3:30 a.m.
Message ID <1e3843795c2cc7b154d9.1416454230@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/6803/
State Changes Requested
Headers show

Comments

Pierre-Yves David - Nov. 20, 2014, 3:30 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1415877546 0
#      Thu Nov 13 11:19:06 2014 +0000
# Node ID 1e3843795c2cc7b154d9dcdd7cd249175f449361
# Parent  2968a06bb0f4ba98e81dfd561444cab20a9af683
transaction: support cache for file generator

One can now record a file generator as "cache". Failure to generate, backup, or
restore such file will be ignored.

Patch

diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -237,11 +237,11 @@  class transaction(object):
         """
         self._addbackupentry((location, '', tmpfile, False))
 
     @active
     def addfilegenerator(self, genid, filenames, genfunc, order=0,
-                         location=''):
+                         location='', cache=False):
         """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.
 
@@ -259,32 +259,50 @@  class transaction(object):
         generator will be executed.
 
         The `location` arguments may be used to indicate the files are located
         outside of the the standard directory for transaction. It should match
         one of the key of the `transaction.vfsmap` dictionnary.
+
+        The `cache` argument can be set to True to mark the generators as
+        "related to cache" error during generator or backup will be ignored.
         """
         # For now, we are unable to do proper backup and restore of custom vfs
         # but for bookmarks that are handled outside this mechanism.
-        self._filegenerators[genid] = (order, filenames, genfunc, location)
+        entry = (order, filenames, genfunc, location, cache)
+        self._filegenerators[genid] = entry
 
     def _generatefiles(self, suffix=''):
         # write files registered for generation
         any = False
-        for entry in sorted(self._filegenerators.values()):
+        genitems = self._filegenerators.items()
+        for genid, entry in sorted(genitems, key=lambda x: x[1]):
             any = True
-            order, filenames, genfunc, location = entry
+            order, filenames, genfunc, location, cache = entry
+            if cache and location not in self._vfsmap:
+                self.report("couldn't generate %s: unknown cache location %s\n"
+                            % (genid, location))
+                continue
+
             vfs = self._vfsmap[location]
             files = []
             try:
-                for name in filenames:
-                    name += suffix
-                    if suffix:
-                        self.registertmp(name, location=location)
-                    else:
-                        self.addbackup(name, location=location)
-                    files.append(vfs(name, 'w', atomictemp=True))
-                genfunc(*files)
+                try:
+                    for name in filenames:
+                        name += suffix
+                        if suffix:
+                            self.registertmp(name, location=location)
+                        else:
+                            self.addbackup(name, location=location,
+                                           cache=cache)
+                        files.append(vfs(name, 'w', atomictemp=True))
+                    genfunc(*files)
+                except (IOError, OSError, util.Abort), inst:
+                    if not cache:
+                        raise
+                    # Abort may be raise by read only opener
+                    self.report("couldn't write generate file for %s: %s\n"
+                                % (genid, inst))
             finally:
                 for f in files:
                     f.close()
         return any