[PATCH] Allow manipulating files with long names on Windows
Adrian Buehlmann
adrian at cadifra.com
Mon Jan 17 12:31:32 CST 2011
On 2011-01-17 08:59, Aaron Cohen wrote:
> # HG changeset patch
> # User Aaron Cohen <aaron at assonance.org>
> # Date 1295249042 18000
> # Node ID 8b2e02872bc83f9e537a9754ce4b7bd0d9a5d9aa
> # Parent 20a54bdf232832d3d6c4e4a43361dc84ec73dca0
> Allow manipulating files with long names on Windows
>
> Windows by default has a PATH_MAX of 260 characters. A while ago the
Windows does not define PATH_MAX. It has a MAX_PATH which is 260.
> "store" format was added which allows repositories on Windows to
> contain very long paths.
It was the fncache format which made that possible.
http://mercurial.selenic.com/wiki/fncacheRepoFormat
[big snip]
> diff -r 20a54bdf2328 -r 8b2e02872bc8 tests/test-win32lfn.py
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/tests/test-win32lfn.py Mon Jan 17 02:24:02 2011 -0500
> @@ -0,0 +1,99 @@
> +import os, errno
> +
> +from hgext import win32lfn
> +
> +win32lfn.uisetup(None)
> +
> +# 299 chars, mixed slashes
> +name = "123456789\\" + 28 * "123456789/" + "123456789"
> +
> +uncname = win32lfn.unc(name)
> +
> +expectedpath = "\\\\?\\" + os.getcwd() + 30 * "\\123456789"
> +
> +assert uncname == expectedpath
> +
> +convolutedpath = "C:\\d/d\\d/././.\\..\\\\//."
> +
> +canonpath = win32lfn.unc(convolutedpath)
> +expected = "\\\\?\\C:\\d\\d"
> +assert canonpath == expected
> +
> +normpath = os.path.normpath(convolutedpath)
> +expected = "C:\\d\\d"
> +assert normpath == expected
> +
> +shortpath = "C:\\"
> +shortunc = win32lfn.unc(shortpath)
> +expected = "\\\\?\\C:\\"
> +assert shortunc == expected
> +
> +assert os.path.dirname(shortunc) == shortunc
> +
> +head, tail = os.path.split(shortunc)
> +expected = "\\\\?\\C:\\"
> +assert head == expected, tail == ""
> +
> +# Tempting as it is, make sure we don't touch paths that were already UNC
> +assert win32lfn.unc("\\\\?\\" + convolutedpath) == "\\\\?\\" + convolutedpath
> +
> +# Cleanup previous test runs
> +if os.path.exists(name):
> + for f in os.listdir(name):
> + os.remove(os.path.join(name, f))
> + os.removedirs(name)
> +
> +for d in [name, uncname]:
> + f1 = os.path.join(d, "f1")
> + f2 = os.path.join(d, "f2")
> +
> + assert os.path.split(f1) == (d, "f1")
> + assert os.path.dirname(f2) == d
> + assert os.path.basename(f2) == "f2"
> +
> + os.makedirs(d)
> + assert os.path.exists(d)
> + assert os.path.isdir(d)
> +
> + os.rmdir(d)
> + assert not os.path.exists(d)
> +
> + # os.mkdir must return EEXIST if the directory exists
> + os.mkdir(d)
> + thrown = False
> + try:
> + os.mkdir(name)
> + except OSError, err:
> + thrown = True
> + assert err.errno == errno.EEXIST
> + assert thrown
> +
> + f = open(f1, 'w')
> + f.write("Test")
> + f.close()
> +
> + f = open(f1, 'r')
> + assert f.readline() == "Test"
> + f.close()
> +
> + os.stat(f1)
> + os.lstat(f1)
> + os.chmod(f1, 660)
> + assert os.path.isfile(f1)
> +
> + files = os.listdir(name)
> + assert len(files) == 1
> + assert os.path.basename(f1) in files
> +
> + os.rename(f1, f2)
> + os.stat(f2)
> + assert not os.path.exists(f1)
> +
> + fd = os.open(f1, os.O_CREAT | os.O_BINARY | os.O_RDWR)
> + os.write(fd, "Test2")
> + os.close(fd)
> +
> + os.remove(f1)
> + os.unlink(f2)
> + os.removedirs(name)
> + assert not os.path.exists("123456789")
> \ No newline at end of file
Please end the files with a newline.
I don't see any test cases using util.posixfile here. And I have some
doubts the extension works with util.posixfile on Windows. Can you prove
me wrong?
(util.posixfile is pretty heavily used by Mercurial on Windows)
More information about the Mercurial-devel
mailing list