D3439: templatefilters: add commonprefix

2018-06-13 Thread yuja (Yuya Nishihara)
yuja added a comment.


  >   > `commondir()` would be fine as well. `commonpath()` doesn't feel 
better. I'm ambivalent about either nam>
  >   I'd vote for changing it then. Both because I think it might make it 
clearer that it's the common prefix of "foo/bar" and "food" is not "foo" and 
because, as I said, we might want such a function later and it would be 
unfortunate if the name was taken. Btw, I just checked and we already have 
`dirname()` and `stripdir()` functions that would match `commondir()`.
  
  +1 for `commondir()`. It matches the actual behavior, which is the last 
filename
  part is always stripped.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: martinvonz, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D3439: templatefilters: add commonprefix

2018-06-13 Thread Yuya Nishihara
>   > `commondir()` would be fine as well. `commonpath()` doesn't feel better. 
> I'm ambivalent about either nam>
>   I'd vote for changing it then. Both because I think it might make it 
> clearer that it's the common prefix of "foo/bar" and "food" is not "foo" and 
> because, as I said, we might want such a function later and it would be 
> unfortunate if the name was taken. Btw, I just checked and we already have 
> `dirname()` and `stripdir()` functions that would match `commondir()`.

+1 for `commondir()`. It matches the actual behavior, which is the last filename
part is always stripped.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-06-12 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  In https://phab.mercurial-scm.org/D3439#58410, @joerg.sonnenberger wrote:
  
  > In https://phab.mercurial-scm.org/D3439#58405, @martinvonz wrote:
  >
  > > Do you think we should call it `commonpath()` or `commondir()` instead in 
case we want `commonprefix()` to work for any string in the future (and not 
care about path separators)?
  >
  >
  > `commondir()` would be fine as well. `commonpath()` doesn't feel better. 
I'm ambivalent about either name.
  
  
  I'd vote for changing it then. Both because I think it might make it clearer 
that it's the common prefix of "foo/bar" and "food" is not "foo" and because, 
as I said, we might want such a function later and it would be unfortunate if 
the name was taken. Btw, I just checked and we already have `dirname()` and 
`stripdir()` functions that would match `commondir()`.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: martinvonz, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-06-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger added a comment.


  In https://phab.mercurial-scm.org/D3439#58405, @martinvonz wrote:
  
  > Do you think we should call it `commonpath()` or `commondir()` instead in 
case we want `commonprefix()` to work for any string in the future (and not 
care about path separators)?
  
  
  `commondir()` would be fine as well. `commonpath()` doesn't feel better. I'm 
ambivalent about either name.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: martinvonz, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-06-12 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  Do you think we should call it `commonpath()` or `commondir()` instead in 
case we want `commonprefix()` to work for any string in the future (and not 
care about path separators)?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: martinvonz, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D3439: templatefilters: add commonprefix

2018-06-02 Thread Yuya Nishihara
For the record, I still believe the commonprefix of a pair of identical paths
should be the path itself as it is the longest sub-component of these paths.

> > +  $ hg debugtemplate '{"foo/bar\nfoo/bar\n"|splitlines|commonprefix}\n'
> > +  foo
> 
> should be "foo/bar"

And removing the leading slash is awkward.

> > +  $ hg debugtemplate '{"/foo/bar\n/foo/bar\n"|splitlines|commonprefix}\n'
> > +  foo
> 
> should be "/foo/bar"
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-06-02 Thread yuja (Yuya Nishihara)
yuja added a comment.


  For the record, I still believe the commonprefix of a pair of identical paths
  should be the path itself as it is the longest sub-component of these paths.
  
  >> +  $ hg debugtemplate '{"foo/bar\nfoo/bar\n"|splitlines|commonprefix}\n'
  >  > +  foo
  > 
  > should be "foo/bar"
  
  And removing the leading slash is awkward.
  
  >> +  $ hg debugtemplate '{"/foo/bar\n/foo/bar\n"|splitlines|commonprefix}\n'
  >  > +  foo
  > 
  > should be "/foo/bar"

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-06-01 Thread joerg.sonnenberger (Joerg Sonnenberger)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG56dd15178190: templatefilters: add commonprefix (authored 
by joerg.sonnenberger, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D3439?vs=8614=8946#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8614=8946

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-10 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 8614.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8595=8614

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import functools
 import os
 import re
 import time
@@ -99,6 +100,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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D3439: templatefilters: add commonprefix

2018-05-10 Thread Yuya Nishihara
> +  $ hg debugtemplate '{"foo/bar\nfoo/bar\n"|splitlines|commonprefix}\n'
> +  foo

should be "foo/bar"

> +  $ hg debugtemplate '{"/foo/bar\n/foo/bar\n"|splitlines|commonprefix}\n'
> +  foo

should be "/foo/bar"

> +  $ hg debugtemplate '{"/foo\n/foo\n"|splitlines|commonprefix}\n'
> +  

should e "/foo"

FWIW, I doubt if scanning all elements with the seen set is faster than
calling min()/max() to pick the farthest pair because Python is slow.

> {str|commonprefix} is not really interesting since it is naturally an
> iterable of text.

I think it's better to error out, but that could be addressed later.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-10 Thread yuja (Yuya Nishihara)
yuja added a comment.


  > +  $ hg debugtemplate '{"foo/bar\nfoo/bar\n"|splitlines|commonprefix}\n'
  >  +  foo
  
  should be "foo/bar"
  
  > +  $ hg debugtemplate '{"/foo/bar\n/foo/bar\n"|splitlines|commonprefix}\n'
  >  +  foo
  
  should be "/foo/bar"
  
  > +  $ hg debugtemplate '{"/foo\n/foo\n"|splitlines|commonprefix}\n'
  >  +
  
  should e "/foo"
  
  FWIW, I doubt if scanning all elements with the seen set is faster than
  calling min()/max() to pick the farthest pair because Python is slow.
  
  > {str|commonprefix} is not really interesting since it is naturally an
  >  iterable of text.
  
  I think it's better to error out, but that could be addressed later.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-09 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 8595.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8593=8595

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import functools
 import os
 import re
 import time
@@ -99,6 +100,46 @@
 """
 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 "".
+"""
+seen = set()
+def common(a, b):
+if b in seen:
+return a
+seen.add(b)
+if len(a) > len(b):
+a = b[:len(a)]
+seen.add(a)
+elif len(b) > len(a):
+b = b[:len(a)]
+if b in seen:
+return a
+seen.add(b)
+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 = [tuple(f.lstrip('/').split('/')[:-1]) for f in filelist]
+return '/'.join(functools.reduce(common, dirlist))
+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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-09 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger added a comment.


  {str|commonprefix} is not really interesting since it is naturally an 
iterable of text. The others are covered, the routine tries to optimize a 
couple of common cases as well now.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-09 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 8593.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8590=8593

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -0,0 +1,21 @@
+  $ hg debugtemplate '{""|splitlines|commonprefix}\n'
+  
+  $ hg debugtemplate '{"foo/bar\nfoo/baz\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\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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import functools
 import os
 import re
 import time
@@ -99,6 +100,38 @@
 """
 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 "".
+"""
+seen = set()
+def common(a, b):
+if b in seen:
+return a
+seen.add(b)
+if len(a) > len(b):
+a, b = b, a
+for i in xrange(len(a)):
+if a[i] != b[i]:
+return a[:i]
+return a
+try:
+if not filelist:
+return ""
+dirlist = [tuple(f.lstrip('/').split('/')[:-1]) for f in filelist]
+return '/'.join(functools.reduce(common, dirlist))
+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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-09 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Please add tests of edge cases.
  
  - `str|commonprefix`
  - infinite loop (e.g. `["/foo", "bar"]`)
  - exact match (e.g. `["/foo"]` and `["/foo", "/foo"]`)
  - empty list
  
  `os.path.commonprefix()` will provide some hints to avoid comparison of
  all list elements by using min()/max().

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D3439: templatefilters: add commonprefix

2018-05-09 Thread Yuya Nishihara
Please add tests of edge cases.

 - `str|commonprefix`
 - infinite loop (e.g. `["/foo", "bar"]`)
 - exact match (e.g. `["/foo"]` and `["/foo", "/foo"]`)
 - empty list

`os.path.commonprefix()` will provide some hints to avoid comparison of
all list elements by using min()/max().
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-08 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 8590.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8549=8590

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -0,0 +1,11 @@
+  $ hg debugtemplate '{"foo/bar\nfoo/baz\n"|splitlines|commonprefix}\n'
+  foo
+  $ hg debugtemplate '{"foo/bar\nbar/baz"|splitlines|commonprefix}\n'
+  
+  $ hg debugtemplate '{"foo/../bar\nfoo/bar"|splitlines|commonprefix}\n'
+  foo
+  $ 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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import functools
 import os
 import re
 import time
@@ -99,6 +100,33 @@
 """
 return os.path.basename(path)
 
+@templatefilter('commonprefix')
+def commonprefix(filelist):
+"""List of text. Treats each list item as file name, 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/..".
+
+For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and
+["foo/bar", "baz"] becomes "".
+"""
+def common(a, b):
+while a != b:
+if len(a) > len(b):
+a = os.path.dirname(a)
+else:
+b = os.path.dirname(b)
+return a
+try:
+if not filelist:
+return ""
+dirlist = [os.path.dirname(f) for f in filelist]
+return functools.reduce(common, dirlist)
+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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3439: templatefilters: add commonprefix

2018-05-08 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 8549.
joerg.sonnenberger retitled this revision from "template filters: add 
commonprefix" to "templatefilters: add commonprefix".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3439?vs=8454=8549

REVISION DETAIL
  https://phab.mercurial-scm.org/D3439

AFFECTED FILES
  mercurial/templatefilters.py
  tests/test-template-filters.t

CHANGE DETAILS

diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -0,0 +1,11 @@
+  $ hg debugtemplate '{"foo/bar\nfoo/baz\n"|splitlines|commonprefix}\n'
+  foo
+  $ hg debugtemplate '{"foo/bar\nbar/baz"|splitlines|commonprefix}\n'
+  
+  $ hg debugtemplate '{"foo/../bar\nfoo/bar"|splitlines|commonprefix}\n'
+  foo
+  $ 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]
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -99,6 +99,33 @@
 """
 return os.path.basename(path)
 
+@templatefilter('commonprefix')
+def commonprefix(filelist):
+"""List of text. Treats each list item as file name, 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/..".
+
+For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and
+["foo/bar", "baz"] becomes "".
+"""
+def common(a, b):
+while a != b:
+if len(a) > len(b):
+a = os.path.dirname(a)
+else:
+b = os.path.dirname(b)
+return a
+try:
+if not filelist:
+return ""
+dirlist = [os.path.dirname(f) for f in filelist]
+return reduce(common, dirlist)
+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."""



To: joerg.sonnenberger, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel