Patchwork [1,of,9] fileset: add helpers to make predicatematcher and nevermatcher

login
register
mail settings
Submitter Yuya Nishihara
Date July 10, 2018, 3:07 p.m.
Message ID <79b280fd446047cbc758.1531235259@mimosa>
Download mbox | patch
Permalink /patch/32759/
State Accepted
Headers show

Comments

Yuya Nishihara - July 10, 2018, 3:07 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1528628573 -32400
#      Sun Jun 10 20:02:53 2018 +0900
# Node ID 79b280fd446047cbc75834aafad75b4d2290aa9b
# Parent  cfcd2617ce7319dfda124b20d64dbd9abe7cdf2a
fileset: add helpers to make predicatematcher and nevermatcher

These functions will be used to compose a tree of matchers from a fileset
expression.

Patch

diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -7,6 +7,7 @@ 
 
 from __future__ import absolute_import
 
+import errno
 import re
 
 from .i18n import _
@@ -563,8 +564,56 @@  class matchctx(object):
         self._existingenabled = False
     def status(self):
         return self._status
+
     def matcher(self, patterns):
         return self.ctx.match(patterns, badfn=self._badfn)
+
+    def predicate(self, predfn, predrepr=None, cache=False):
+        """Create a matcher to select files by predfn(filename)"""
+        if cache:
+            predfn = util.cachefunc(predfn)
+        repo = self.ctx.repo()
+        return matchmod.predicatematcher(repo.root, repo.getcwd(), predfn,
+                                         predrepr=predrepr, badfn=self._badfn)
+
+    def fpredicate(self, predfn, predrepr=None, cache=False):
+        """Create a matcher to select files by predfn(fctx) at the current
+        revision
+
+        Missing files are ignored.
+        """
+        ctx = self.ctx
+        if ctx.rev() is None:
+            def fctxpredfn(f):
+                try:
+                    fctx = ctx[f]
+                except error.LookupError:
+                    return False
+                try:
+                    fctx.audit()
+                except error.Abort:
+                    return False
+                try:
+                    return predfn(fctx)
+                except (IOError, OSError) as e:
+                    if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EISDIR):
+                        return False
+                    raise
+        else:
+            def fctxpredfn(f):
+                try:
+                    fctx = ctx[f]
+                except error.LookupError:
+                    return False
+                return predfn(fctx)
+        return self.predicate(fctxpredfn, predrepr=predrepr, cache=cache)
+
+    def never(self):
+        """Create a matcher to select nothing"""
+        repo = self.ctx.repo()
+        return matchmod.nevermatcher(repo.root, repo.getcwd(),
+                                     badfn=self._badfn)
+
     def filter(self, files):
         return [f for f in files if f in self.subset]
     def existing(self):