##// END OF EJS Templates
util: extract stringmatcher() from revset...
Matt Harbison -
r26481:7d132557 default
parent child Browse files
Show More
@@ -690,7 +690,7 b' def bookmark(repo, subset, x):'
690 bm = getstring(args[0],
690 bm = getstring(args[0],
691 # i18n: "bookmark" is a keyword
691 # i18n: "bookmark" is a keyword
692 _('the argument to bookmark must be a string'))
692 _('the argument to bookmark must be a string'))
693 kind, pattern, matcher = _stringmatcher(bm)
693 kind, pattern, matcher = util.stringmatcher(bm)
694 bms = set()
694 bms = set()
695 if kind == 'literal':
695 if kind == 'literal':
696 bmrev = repo._bookmarks.get(pattern, None)
696 bmrev = repo._bookmarks.get(pattern, None)
@@ -731,7 +731,7 b' def branch(repo, subset, x):'
731 # not a string, but another revspec, e.g. tip()
731 # not a string, but another revspec, e.g. tip()
732 pass
732 pass
733 else:
733 else:
734 kind, pattern, matcher = _stringmatcher(b)
734 kind, pattern, matcher = util.stringmatcher(b)
735 if kind == 'literal':
735 if kind == 'literal':
736 # note: falls through to the revspec case if no branch with
736 # note: falls through to the revspec case if no branch with
737 # this name exists
737 # this name exists
@@ -1019,7 +1019,7 b' def extra(repo, subset, x):'
1019 # i18n: "extra" is a keyword
1019 # i18n: "extra" is a keyword
1020 value = getstring(args['value'], _('second argument to extra must be '
1020 value = getstring(args['value'], _('second argument to extra must be '
1021 'a string'))
1021 'a string'))
1022 kind, value, matcher = _stringmatcher(value)
1022 kind, value, matcher = util.stringmatcher(value)
1023
1023
1024 def _matchvalue(r):
1024 def _matchvalue(r):
1025 extra = repo[r].extra()
1025 extra = repo[r].extra()
@@ -1466,7 +1466,7 b' def named(repo, subset, x):'
1466 ns = getstring(args[0],
1466 ns = getstring(args[0],
1467 # i18n: "named" is a keyword
1467 # i18n: "named" is a keyword
1468 _('the argument to named must be a string'))
1468 _('the argument to named must be a string'))
1469 kind, pattern, matcher = _stringmatcher(ns)
1469 kind, pattern, matcher = util.stringmatcher(ns)
1470 namespaces = set()
1470 namespaces = set()
1471 if kind == 'literal':
1471 if kind == 'literal':
1472 if pattern not in repo.names:
1472 if pattern not in repo.names:
@@ -2034,7 +2034,7 b' def subrepo(repo, subset, x):'
2034 m = matchmod.exact(repo.root, repo.root, ['.hgsubstate'])
2034 m = matchmod.exact(repo.root, repo.root, ['.hgsubstate'])
2035
2035
2036 def submatches(names):
2036 def submatches(names):
2037 k, p, m = _stringmatcher(pat)
2037 k, p, m = util.stringmatcher(pat)
2038 for name in names:
2038 for name in names:
2039 if m(name):
2039 if m(name):
2040 yield name
2040 yield name
@@ -2064,47 +2064,8 b' def subrepo(repo, subset, x):'
2064
2064
2065 return subset.filter(matches)
2065 return subset.filter(matches)
2066
2066
2067 def _stringmatcher(pattern):
2068 """
2069 accepts a string, possibly starting with 're:' or 'literal:' prefix.
2070 returns the matcher name, pattern, and matcher function.
2071 missing or unknown prefixes are treated as literal matches.
2072
2073 helper for tests:
2074 >>> def test(pattern, *tests):
2075 ... kind, pattern, matcher = _stringmatcher(pattern)
2076 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2077
2078 exact matching (no prefix):
2079 >>> test('abcdefg', 'abc', 'def', 'abcdefg')
2080 ('literal', 'abcdefg', [False, False, True])
2081
2082 regex matching ('re:' prefix)
2083 >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
2084 ('re', 'a.+b', [False, False, True])
2085
2086 force exact matches ('literal:' prefix)
2087 >>> test('literal:re:foobar', 'foobar', 're:foobar')
2088 ('literal', 're:foobar', [False, True])
2089
2090 unknown prefixes are ignored and treated as literals
2091 >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
2092 ('literal', 'foo:bar', [False, False, True])
2093 """
2094 if pattern.startswith('re:'):
2095 pattern = pattern[3:]
2096 try:
2097 regex = re.compile(pattern)
2098 except re.error as e:
2099 raise error.ParseError(_('invalid regular expression: %s')
2100 % e)
2101 return 're', pattern, regex.search
2102 elif pattern.startswith('literal:'):
2103 pattern = pattern[8:]
2104 return 'literal', pattern, pattern.__eq__
2105
2106 def _substringmatcher(pattern):
2067 def _substringmatcher(pattern):
2107 kind, pattern, matcher = _stringmatcher(pattern)
2068 kind, pattern, matcher = util.stringmatcher(pattern)
2108 if kind == 'literal':
2069 if kind == 'literal':
2109 matcher = lambda s: pattern in s
2070 matcher = lambda s: pattern in s
2110 return kind, pattern, matcher
2071 return kind, pattern, matcher
@@ -2124,7 +2085,7 b' def tag(repo, subset, x):'
2124 pattern = getstring(args[0],
2085 pattern = getstring(args[0],
2125 # i18n: "tag" is a keyword
2086 # i18n: "tag" is a keyword
2126 _('the argument to tag must be a string'))
2087 _('the argument to tag must be a string'))
2127 kind, pattern, matcher = _stringmatcher(pattern)
2088 kind, pattern, matcher = util.stringmatcher(pattern)
2128 if kind == 'literal':
2089 if kind == 'literal':
2129 # avoid resolving all tags
2090 # avoid resolving all tags
2130 tn = repo._tagscache.tags.get(pattern, None)
2091 tn = repo._tagscache.tags.get(pattern, None)
@@ -1605,6 +1605,45 b' def matchdate(date):'
1605 start, stop = lower(date), upper(date)
1605 start, stop = lower(date), upper(date)
1606 return lambda x: x >= start and x <= stop
1606 return lambda x: x >= start and x <= stop
1607
1607
1608 def stringmatcher(pattern):
1609 """
1610 accepts a string, possibly starting with 're:' or 'literal:' prefix.
1611 returns the matcher name, pattern, and matcher function.
1612 missing or unknown prefixes are treated as literal matches.
1613
1614 helper for tests:
1615 >>> def test(pattern, *tests):
1616 ... kind, pattern, matcher = stringmatcher(pattern)
1617 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
1618
1619 exact matching (no prefix):
1620 >>> test('abcdefg', 'abc', 'def', 'abcdefg')
1621 ('literal', 'abcdefg', [False, False, True])
1622
1623 regex matching ('re:' prefix)
1624 >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
1625 ('re', 'a.+b', [False, False, True])
1626
1627 force exact matches ('literal:' prefix)
1628 >>> test('literal:re:foobar', 'foobar', 're:foobar')
1629 ('literal', 're:foobar', [False, True])
1630
1631 unknown prefixes are ignored and treated as literals
1632 >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
1633 ('literal', 'foo:bar', [False, False, True])
1634 """
1635 if pattern.startswith('re:'):
1636 pattern = pattern[3:]
1637 try:
1638 regex = remod.compile(pattern)
1639 except remod.error as e:
1640 raise error.ParseError(_('invalid regular expression: %s')
1641 % e)
1642 return 're', pattern, regex.search
1643 elif pattern.startswith('literal:'):
1644 pattern = pattern[8:]
1645 return 'literal', pattern, pattern.__eq__
1646
1608 def shortuser(user):
1647 def shortuser(user):
1609 """Return a short representation of a user name or email address."""
1648 """Return a short representation of a user name or email address."""
1610 f = user.find('@')
1649 f = user.find('@')
General Comments 0
You need to be logged in to leave comments. Login now