pathutil: add dirname and join functions
authorDurham Goode <durham@fb.com>
Fri, 22 May 2015 12:47:18 -0700
changeset 25281 660b178f49c7
parent 25280 8c8af4d8aca3
child 25282 0f28815ef066
pathutil: add dirname and join functions This adds dirname and join functions to pathutil which are explicitly for handling '/' delimited paths. The implementations are basically copy paste from python's posix os.path.dirname and os.path.join functions.
mercurial/pathutil.py
--- a/mercurial/pathutil.py	Thu May 21 15:44:38 2015 -0700
+++ b/mercurial/pathutil.py	Fri May 22 12:47:18 2015 -0700
@@ -187,3 +187,68 @@
         return path + os.sep
     else:
         return path
+
+def join(path, *paths):
+    '''Join two or more pathname components, inserting '/' as needed.
+
+    Based on the posix os.path.join() implementation.
+
+    >>> join('foo', 'bar')
+    'foo/bar'
+    >>> join('/foo', 'bar')
+    '/foo/bar'
+    >>> join('foo', '/bar')
+    '/bar'
+    >>> join('foo', 'bar/')
+    'foo/bar/'
+    >>> join('foo', 'bar', 'gah')
+    'foo/bar/gah'
+    >>> join('foo')
+    'foo'
+    >>> join('', 'foo')
+    'foo'
+    >>> join('foo/', 'bar')
+    'foo/bar'
+    >>> join('', '', '')
+    ''
+    >>> join ('foo', '', '', 'bar')
+    'foo/bar'
+    '''
+    sep = '/'
+    if not paths:
+        path[:0] + sep #23780: Ensure compatible data type even if p is null.
+    for piece in paths:
+        if piece.startswith(sep):
+            path = piece
+        elif not path or path.endswith(sep):
+            path += piece
+        else:
+            path += sep + piece
+    return path
+
+def dirname(path):
+    '''returns the directory portion of the given path
+
+    Based on the posix os.path.split() implementation.
+
+    >>> dirname('foo')
+    ''
+    >>> dirname('foo/')
+    'foo'
+    >>> dirname('foo/bar')
+    'foo'
+    >>> dirname('/foo')
+    '/'
+    >>> dirname('/foo/bar')
+    '/foo'
+    >>> dirname('/foo//bar/poo')
+    '/foo//bar'
+    >>> dirname('/foo//bar')
+    '/foo'
+    '''
+    sep = '/'
+    i = path.rfind(sep) + 1
+    dirname = path[:i]
+    if dirname and dirname != sep * len(dirname):
+        dirname = dirname.rstrip(sep)
+    return dirname