Submitter | Durham Goode |
---|---|
Date | May 22, 2015, 8:50 p.m. |
Message ID | <53d97bfd60a1d5e397b8.1432327815@dev2000.prn2.facebook.com> |
Download | mbox | patch |
Permalink | /patch/9242/ |
State | Accepted |
Delegated to: | Augie Fackler |
Headers | show |
Comments
On Fri, May 22, 2015 at 01:50:15PM -0700, Durham Goode wrote: > # HG changeset patch > # User Durham Goode <durham@fb.com> > # Date 1432324038 25200 > # Fri May 22 12:47:18 2015 -0700 > # Node ID 53d97bfd60a1d5e397b808def920fe6a73a1cac6 > # Parent f2b98dacb37ddd6713b11a1a871fcdbbc5fd8bb2 > 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. Why not just *use* posixpath.join() et al in these methods, rather than carrying around a bonus implementation? > > diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py > --- a/mercurial/pathutil.py > +++ b/mercurial/pathutil.py > @@ -187,3 +187,68 @@ def normasprefix(path): > 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 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel
On 5/26/15 8:01 AM, Augie Fackler wrote: > On Fri, May 22, 2015 at 01:50:15PM -0700, Durham Goode wrote: >> # HG changeset patch >> # User Durham Goode <durham@fb.com> >> # Date 1432324038 25200 >> # Fri May 22 12:47:18 2015 -0700 >> # Node ID 53d97bfd60a1d5e397b808def920fe6a73a1cac6 >> # Parent f2b98dacb37ddd6713b11a1a871fcdbbc5fd8bb2 >> 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. > Why not just *use* posixpath.join() et al in these methods, rather > than carrying around a bonus implementation? I didn't realize it existed. I'll resend with them.
On Wed, May 27, 2015 at 2:04 PM, Durham Goode <durham@fb.com> wrote: >> Why not just *use* posixpath.join() et al in these methods, rather >> than carrying around a bonus implementation? > > I didn't realize it existed. I'll resend with them. These are already pushed with that fixed in a followup. :)
Patch
diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py --- a/mercurial/pathutil.py +++ b/mercurial/pathutil.py @@ -187,3 +187,68 @@ def normasprefix(path): 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