annotate cutils/util/fnmatch.py @ 368:7761a15b9736

treesum: Escape `\' using `\\' instead of `\x5c'. Wished by sbro. BUGS: Escaping should be controllable by a commandline option.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 10 Apr 2025 11:58:36 +0200
parents 48430941c18c
children 54a6d4534ef4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
300
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
2 # :-
323
48430941c18c Adopt copyright and license wordings from https://reuse.software/faq/.
Franz Glasner <fzglas.hg@dom66.de>
parents: 312
diff changeset
3 # SPDX-FileCopyrightText: © 2025 Franz Glasner
48430941c18c Adopt copyright and license wordings from https://reuse.software/faq/.
Franz Glasner <fzglas.hg@dom66.de>
parents: 312
diff changeset
4 # SPDX-License-Identifier: BSD-3-Clause
300
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
5 # :-
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
6 r"""File name matching.
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
7
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
8 """
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
9
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
10 from __future__ import print_function, absolute_import
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
11
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
12
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
13 __all__ = ["FnMatcher"]
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
14
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
15
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
16 import re
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
17
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
18 from . import PY2
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
19 from . import glob
300
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
20
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
21
312
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
22 HELP_DESCRIPTION = r"""
300
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
23 PATTERNs
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
24 ========
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
25
312
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
26 Filename matching allows several types of patterns. Each pattern starts
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
27 with its type specification.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
28
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
29 glob:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
30 case-sensitive, anchored at the begin and end
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
31
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
32 iglob:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
33 case-insensitive variant of "glob"
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
34
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
35 re:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
36 regular expression (Python style)
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
37
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
38 path:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
39 plain path name (rooted), can be a file or a directory or a prefix
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
40 thereof
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
41
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
42 fullpath:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
43 exactly a single full path (file or directory), relative to the
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
44 root of the tree
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
45
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
46 The default if no type is given explicitely is "glob:".
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
47
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
48
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
49 Glob Syntax Rules
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
50 -----------------
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
51
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
52 - The `*' character matches zero or more characters of a name
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
53 component without crossing directory boundaries.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
54
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
55 - The `**' characters matches zero or more characters crossing
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
56 directory boundaries.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
57
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
58 - `**/' matches zero or more subdirectories; files do not match.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
59
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
60 - The `?' character matches exactly one character of a name component.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
61
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
62 - The backslash character (`\') is used to escape characters that
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
63 would otherwise be interpreted as special characters. The expression
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
64 `\\' matches a single backslash and `\{' matches a left brace for
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
65 example.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
66
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
67 - The `[ ]' characters are a bracket expression that match a single
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
68 character of a name component out of a set of characters. For example,
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
69 `[abc]' matches "a", "b", or "c". The hyphen (`-') may
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
70 be used to specify a range so `[a-z]' specifies a range that matches
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
71 from "a" to "z" (inclusive). These forms can be mixed so
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
72 `[abce-g]' matches "a", "b", "c", "e", "f" or "g".
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
73
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
74 If the character after the `[' is a `!' then it is used for negation
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
75 so `[!a-c]' matches any character except "a", "b", or "c".
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
76
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
77 Within a bracket expression the `*', `?' and `\' characters match
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
78 themselves.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
79
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
80 The `-' character matches itself if it is the first or last character
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
81 within the brackets, or the first or last character after the `!' if
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
82 negating.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
83
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
84 Also, the `]' character matches itself if it is the first character
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
85 within the brackets, or the first character after the `!' if negating.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
86
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
87 - The curly brace characters `{ }' denote a group of subpatterns, where
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
88 the group matches if any subpattern in the group matches.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
89
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
90 The `,' character is used to separate the subpatterns. Groups can be
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
91 nested.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
92
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
93 - Leading period/dot characters in file name are treated as regular characters
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
94 in match operations. For example, the `*' glob pattern matches file name
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
95 `.login'.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
96
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
97 - All other characters match themselves.
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
98
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
99
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
100 Examples
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
101 --------
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
102
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
103 glob:*.py
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
104 any name ending with ".py" in the root directory
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
105
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
106 *.py
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
107 the same as "glob:*.py" (because "glob:" is the default)
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
108
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
109 re:\A[^/]*\.py\Z
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
110 the same as "glob:*.py"
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
111
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
112 glob:**.py
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
113 any name ending with ".py" anywhere
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
114
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
115 re:\.py\Z
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
116 the same as "glob:**.py"
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
117
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
118 glob:dir/*
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
119 any name in directory "dir"
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
120
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
121 Each of these patterns specify any name below directory "dir":
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
122
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
123 glob:dir/**
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
124
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
125 re:\Adir/
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
126
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
127 path:dir/
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
128
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
129 Each of these patterns specify any name in any directory that ends with
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
130 "file":
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
131
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
132 glob:**/file
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
133
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
134 re:(^|/)file\Z
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
135
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
136 These patterns specify a single path:
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
137
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
138 filepath:dir1/dir2/file
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
139
f5f54b9c3552 treesum: Extensively improved "help patterns":
Franz Glasner <fzglas.hg@dom66.de>
parents: 308
diff changeset
140 re:\Adir1/dir2/file\Z
300
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
141
1fc117f5f9a1 treesum: Implement --include/--exclude commandline parsing for file name inclusion and exclusion.
Franz Glasner <fzglas.hg@dom66.de>
parents:
diff changeset
142 """
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
143
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
144
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
145 def glob_factory(pattern):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
146
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
147 cpat = re.compile(
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
148 # automatically anchored
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
149 "\\A{}\\Z".format(glob.glob_to_regexp(pattern)),
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
150 re.DOTALL)
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
151
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
152 def _glob_matcher(s):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
153 return cpat.search(s) is not None
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
154
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
155 return _glob_matcher
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
156
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
157
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
158 def iglob_factory(pattern):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
159
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
160 cpat = re.compile(
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
161 # automatically anchored
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
162 "\\A{}\\Z".format(glob.glob_to_regexp(pattern)),
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
163 re.DOTALL | re.IGNORECASE)
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
164
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
165 def _iglob_matcher(s):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
166 return cpat.search(s) is not None
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
167
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
168 return _iglob_matcher
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
169
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
170
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
171 def re_factory(pattern):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
172
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
173 cpat = re.compile(pattern, re.DOTALL)
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
174
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
175 def _re_matcher(s):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
176 return cpat.search(s) is not None
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
177
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
178 return _re_matcher
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
179
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
180
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
181 def path_factory(pattern):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
182
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
183 def _path_matcher(s):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
184 return s.startswith(pattern)
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
185
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
186 return _path_matcher
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
187
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
188
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
189 def fullpath_factory(pattern):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
190
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
191 def _fullpath_matcher(s):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
192 return s == pattern
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
193
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
194 return _fullpath_matcher
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
195
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
196
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
197 class FnMatcher(object):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
198
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
199 _registry = {
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
200 "glob": glob_factory,
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
201 "iglob": iglob_factory,
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
202 "re": re_factory,
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
203 "path": path_factory,
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
204 "fullpath": fullpath_factory,
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
205 }
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
206
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
207 def __init__(self, matchers):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
208 super(FnMatcher, self).__init__()
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
209 self._matchers = matchers
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
210
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
211 @classmethod
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
212 def build_from_commandline_patterns(klass, filter_definitions):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
213 matchers = []
304
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
214 if filter_definitions:
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
215 for action, kpattern in filter_definitions:
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
216 assert action in ("include", "exclude", "accept-treesum")
304
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
217 kind, sep, pattern = kpattern.partition(':')
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
218 if not sep:
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
219 # use the default
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
220 kind = "glob"
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
221 pattern = kpattern
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
222 factory = klass._registry.get(kind, None)
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
223 if not factory:
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
224 raise RuntimeError("unknown pattern kind: {}".format(kind))
dc1f08937621 FIX: fnmatch: handle None fnmatch filter definitions
Franz Glasner <fzglas.hg@dom66.de>
parents: 302
diff changeset
225 matchers.append((action, kind, factory(pattern), pattern))
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
226 return klass(matchers)
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
227
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
228 def shall_visit(self, fn, default=True):
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
229 visit = default
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
230 for action, kind, matcher, orig_pattern in self._matchers:
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
231 if matcher(fn):
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
232 if action == "include":
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
233 visit = True
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
234 elif action in ("exclude", "accept-treesum"):
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
235 visit = False
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
236 else:
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
237 raise RuntimeError("unknown action: {}".format(action))
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
238 return visit
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
239
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
240 def shall_accept_treesum(self, fn, default=False):
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
241 accept = default
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
242 for action, kind, matcher, orig_pattern in self._matchers:
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
243 if action == "accept-treesum":
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
244 if matcher(fn):
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
245 accept = True
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
246 elif action in ("include", "exclude"):
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
247 pass
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
248 else:
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
249 raise RuntimeError("unknown action: {}".format(action))
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
250 return accept
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
251
302
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
252 def definitions(self):
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
253 for action, kind, matcher, orig_pattern in self._matchers:
bf88323d6bf7 treesum: Implement --exclude/--include.
Franz Glasner <fzglas.hg@dom66.de>
parents: 300
diff changeset
254 yield (action, kind, orig_pattern)
308
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
255
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
256 def __bool__(self):
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
257 return bool(self._matchers)
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
258
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
259 if PY2:
652870b20f9e treesum: Implement --accept-treesum: trust a treesum-file for a directory checksum
Franz Glasner <fzglas.hg@dom66.de>
parents: 305
diff changeset
260 __nonzero__ = __bool__