Mercurial > hg
changeset 38201: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 | c019db5ccfa1 |
children | 45765264ae3a |
files | mercurial/templatefilters.py tests/test-template-filters.t |
diffstat | 2 files changed, 62 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/templatefilters.py Sun May 20 19:07:51 2018 +0530 +++ b/mercurial/templatefilters.py Fri Apr 20 15:21:03 2018 +0200 @@ -99,6 +99,45 @@ """ return os.path.basename(path) +@templatefilter('commonprefix') +def commonprefix(filelist): + """List of text. Treats each list item as file name with / + as path separator and returns the longest common directory + prefix shared by all list items. + Returns the empty string if no common prefix exists. + + The list items are not normalized, i.e. "foo/../bar" is handled as + file "bar" in the directory "foo/..". Leading slashes are ignored. + + For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and + ["foo/bar", "baz"] becomes "". + """ + def common(a, b): + if len(a) > len(b): + a = b[:len(a)] + elif len(b) > len(a): + b = b[:len(a)] + if a == b: + return a + for i in xrange(len(a)): + if a[i] != b[i]: + return a[:i] + return a + try: + if not filelist: + return "" + dirlist = [f.lstrip('/').split('/')[:-1] for f in filelist] + if len(dirlist) == 1: + return '/'.join(dirlist[0]) + a = min(dirlist) + b = max(dirlist) + # The common prefix of a and b is shared with all + # elements of the list since Python sorts lexicographical + # and [1, x] after [1]. + return '/'.join(common(a, b)) + except TypeError: + raise error.ParseError(_('argument is not a list of text')) + @templatefilter('count') def count(i): """List or text. Returns the length as an integer."""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-template-filters.t Fri Apr 20 15:21:03 2018 +0200 @@ -0,0 +1,23 @@ + $ hg debugtemplate '{""|splitlines|commonprefix}\n' + + $ hg debugtemplate '{"foo/bar\nfoo/baz\nfoo/foobar\n"|splitlines|commonprefix}\n' + foo + $ hg debugtemplate '{"foo/bar\nfoo/bar\n"|splitlines|commonprefix}\n' + foo + $ hg debugtemplate '{"/foo/bar\n/foo/bar\n"|splitlines|commonprefix}\n' + foo + $ hg debugtemplate '{"/foo\n/foo\n"|splitlines|commonprefix}\n' + + $ hg debugtemplate '{"foo/bar\nbar/baz"|splitlines|commonprefix}\n' + + $ hg debugtemplate '{"foo/bar\nbar/baz\nbar/foo\n"|splitlines|commonprefix}\n' + + $ hg debugtemplate '{"foo/../bar\nfoo/bar"|splitlines|commonprefix}\n' + foo + $ hg debugtemplate '{"foo\n/foo"|splitlines|commonprefix}\n' + + $ hg init + $ hg log -r null -T '{rev|commonprefix}' + hg: parse error: argument is not a list of text + (template filter 'commonprefix' is not compatible with keyword 'rev') + [255]