[meld] misc: Update path shortening logic for Windows paths (#203)
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] misc: Update path shortening logic for Windows paths (#203)
- Date: Sun, 15 Jul 2018 00:30:09 +0000 (UTC)
commit e2cc43a4e6a13d66a39b0873aac9146a3e1681d5
Author: Kai Willadsen <kai willadsen gmail com>
Date: Sun Jul 15 10:26:50 2018 +1000
misc: Update path shortening logic for Windows paths (#203)
meld/misc.py | 45 ++++++++++++++++++++++++---------------------
test/test_misc.py | 23 +++++++++++++++++++++++
2 files changed, 47 insertions(+), 21 deletions(-)
---
diff --git a/meld/misc.py b/meld/misc.py
index 49f77dc4..1d700d09 100644
--- a/meld/misc.py
+++ b/meld/misc.py
@@ -25,6 +25,7 @@ import os
import re
import shutil
import subprocess
+from pathlib import PurePath
from gi.repository import Gdk
from gi.repository import GLib
@@ -293,30 +294,32 @@ def all_same(iterable):
def shorten_names(*names):
- """Remove redunant parts of a list of names (e.g. /tmp/foo{1,2} -> foo{1,2}
+ """Remove common parts of a list of paths
+
+ For example, `('/tmp/foo1', '/tmp/foo2')` would be summarised as
+ `('foo1', 'foo2')`. Paths that share a basename are distinguished
+ by prepending an indicator, e.g., `('/a/b/c', '/a/d/c')` would be
+ summarised to `['[b] c', '[d] c']`.
"""
- # TODO: Update for different path separators and URIs
- prefix = os.path.commonprefix(names)
- prefixslash = prefix.rfind("/") + 1
- names = [n[prefixslash:] for n in names]
- paths = [n.split("/") for n in names]
+ paths = [PurePath(n) for n in names]
+
+ # Identify the longest common path among the list of path
+ common = set(paths[0].parents)
+ common = common.intersection(*(p.parents for p in paths))
+ common_parent = sorted(common, key=lambda p: -len(p.parts))[0]
+
+ paths = [p.relative_to(common_parent) for p in paths]
+ basenames = [p.name for p in paths]
+
+ if all_same(basenames):
+ def firstpart(path: PurePath):
+ if len(path.parts) > 1 and path.parts[0]:
+ return "[%s] " % path.parts[0]
+ else:
+ return ""
+ return [firstpart(p) + p.name for p in paths]
- try:
- basenames = [p[-1] for p in paths]
- except IndexError:
- pass
- else:
- if all_same(basenames):
- def firstpart(alist):
- if len(alist) > 1 and alist[0]:
- return "[%s] " % alist[0]
- else:
- return ""
- roots = [firstpart(p) for p in paths]
- base = basenames[0].strip()
- return [r + base for r in roots]
- # no common path. empty names get changed to "[None]"
return [name or _("[None]") for name in basenames]
diff --git a/test/test_misc.py b/test/test_misc.py
index 334be727..47cc900a 100644
--- a/test/test_misc.py
+++ b/test/test_misc.py
@@ -1,4 +1,6 @@
+from unittest import mock
+
import pytest
from meld.misc import all_same, calc_syncpoint, merge_intervals
@@ -73,3 +75,24 @@ def test_calc_syncpoint(value, page_size, lower, upper, expected):
])
def test_all_same(lst, expected):
assert all_same(lst) == expected
+
+
+@pytest.mark.parametrize("os_name, paths, expected", [
+ ('posix', ['/tmp/foo1', '/tmp/foo2'], ['foo1', 'foo2']),
+ ('posix', ['/tmp/foo1', '/tmp/foo2', '/tmp/foo3'], ['foo1', 'foo2', 'foo3']),
+ ('posix', ['/tmp/bar/foo1', '/tmp/woo/foo2'], ['foo1', 'foo2']),
+ ('posix', ['/tmp/bar/foo1', '/tmp/woo/foo1'], ['[bar] foo1', '[woo] foo1']),
+ ('posix', ['/tmp/bar/foo1', '/tmp/woo/foo1', '/tmp/ree/foo1'], ['[bar] foo1', '[woo] foo1', '[ree]
foo1']),
+ ('posix', ['/tmp/bar/deep/deep', '/tmp/bar/shallow'], ['deep', 'shallow']),
+ ('posix', ['/tmp/bar/deep/deep/foo1', '/tmp/bar/shallow/foo1'], ['[deep] foo1', '[shallow] foo1']),
+ # This case doesn't actually make much sense, so it's not that bad
+ # that our output is... somewhat unclear.
+ ('posix', ['/tmp/bar/subdir/subsub', '/tmp/bar/'], ['subsub', 'bar']),
+ ('nt', ['C:\\Users\\hmm\\bar', 'C:\\Users\\hmm\\foo'], ['bar', 'foo']),
+ ('nt', ['C:\\Users\\bar\\hmm', 'C:\\Users\\foo\\hmm'], ['[bar] hmm', '[foo] hmm']),
+])
+def test_shorten_names(os_name, paths, expected):
+ from meld.misc import shorten_names
+
+ with mock.patch('os.name', os_name):
+ assert shorten_names(*paths) == expected
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]