Mercurial > hg > mercurial-source
comparison mercurial/templatefilters.py @ 38987:56dd15178190
templatefilters: add commonprefix
The commonprefix filter takes a list of files names like files() and
returns the longest directory name common to all elements.
Differential Revision: https://phab.mercurial-scm.org/D3439
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Fri, 20 Apr 2018 15:21:03 +0200 |
parents | f5a1aa8c6987 |
children | 0fe65bb7e160 |
comparison
equal
deleted
inserted
replaced
38986:c019db5ccfa1 | 38987:56dd15178190 |
---|---|
96 """Any text. Treats the text as a path, and returns the last | 96 """Any text. Treats the text as a path, and returns the last |
97 component of the path after splitting by the path separator. | 97 component of the path after splitting by the path separator. |
98 For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "". | 98 For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "". |
99 """ | 99 """ |
100 return os.path.basename(path) | 100 return os.path.basename(path) |
101 | |
102 @templatefilter('commonprefix') | |
103 def commonprefix(filelist): | |
104 """List of text. Treats each list item as file name with / | |
105 as path separator and returns the longest common directory | |
106 prefix shared by all list items. | |
107 Returns the empty string if no common prefix exists. | |
108 | |
109 The list items are not normalized, i.e. "foo/../bar" is handled as | |
110 file "bar" in the directory "foo/..". Leading slashes are ignored. | |
111 | |
112 For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and | |
113 ["foo/bar", "baz"] becomes "". | |
114 """ | |
115 def common(a, b): | |
116 if len(a) > len(b): | |
117 a = b[:len(a)] | |
118 elif len(b) > len(a): | |
119 b = b[:len(a)] | |
120 if a == b: | |
121 return a | |
122 for i in xrange(len(a)): | |
123 if a[i] != b[i]: | |
124 return a[:i] | |
125 return a | |
126 try: | |
127 if not filelist: | |
128 return "" | |
129 dirlist = [f.lstrip('/').split('/')[:-1] for f in filelist] | |
130 if len(dirlist) == 1: | |
131 return '/'.join(dirlist[0]) | |
132 a = min(dirlist) | |
133 b = max(dirlist) | |
134 # The common prefix of a and b is shared with all | |
135 # elements of the list since Python sorts lexicographical | |
136 # and [1, x] after [1]. | |
137 return '/'.join(common(a, b)) | |
138 except TypeError: | |
139 raise error.ParseError(_('argument is not a list of text')) | |
101 | 140 |
102 @templatefilter('count') | 141 @templatefilter('count') |
103 def count(i): | 142 def count(i): |
104 """List or text. Returns the length as an integer.""" | 143 """List or text. Returns the length as an integer.""" |
105 try: | 144 try: |