sapling/eden/scm/edenscm/winutil.py
Muir Manders 44343769f8 collapse edenscm.mercurial package into edenscm
Summary:
We want to rename away from "mercurial". Rather than rename the "mercurial" Python package, we opted to just collapse it into the parent "edenscm" package. This is also a step towards further organizing we want to do around the new project name.

To ease the transition wrt hotfixes, we now replace "edenscm.mercurial" with "mercurial" to fix imports within base64-python extensions.

Reviewed By: sggutier

Differential Revision: D38943169

fbshipit-source-id: 03fa18079c51e2f7fac05d65b127095da3ab7c99
2022-08-24 13:45:53 -07:00

89 lines
2.8 KiB
Python

# Portions Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2.
# Copyright (c) Mercurial Contributors.
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""Utility functions related to Windows support, but which must be callable
on all platforms.
"""
from typing import Optional
from . import i18n
_ = i18n._
_winreservedchars = ':*?"<>|'
_winreservednames = {
"con",
"prn",
"aux",
"nul",
"com1",
"com2",
"com3",
"com4",
"com5",
"com6",
"com7",
"com8",
"com9",
"lpt1",
"lpt2",
"lpt3",
"lpt4",
"lpt5",
"lpt6",
"lpt7",
"lpt8",
"lpt9",
}
def checkwinfilename(path: str) -> "Optional[str]":
r"""Check that the base-relative path is a valid filename on Windows.
Returns None if the path is ok, or a UI string describing the problem.
>>> checkwinfilename("just/a/normal/path")
>>> checkwinfilename("foo/bar/con.xml")
"filename contains 'con', which is reserved on Windows"
>>> checkwinfilename("foo/con.xml/bar")
"filename contains 'con', which is reserved on Windows"
>>> checkwinfilename("foo/bar/xml.con")
>>> checkwinfilename("foo/bar/AUX/bla.txt")
"filename contains 'AUX', which is reserved on Windows"
>>> checkwinfilename("foo/bar/bla:.txt")
"filename contains ':', which is reserved on Windows"
>>> checkwinfilename("foo/bar/b\07la.txt")
"filename contains '\\x07', which is invalid on Windows"
>>> checkwinfilename("foo/bar/bla ")
"filename ends with ' ', which is not allowed on Windows"
>>> checkwinfilename("../bar")
>>> checkwinfilename("foo\\")
"filename ends with '\\', which is invalid on Windows"
>>> checkwinfilename("foo\\/bar")
"directory name ends with '\\', which is invalid on Windows"
"""
if path.endswith("\\"):
return _("filename ends with '\\', which is invalid on Windows")
if "\\/" in path:
return _("directory name ends with '\\', which is invalid on Windows")
for n in path.replace("\\", "/").split("/"):
if not n:
continue
for c in n:
if c in _winreservedchars:
return _("filename contains '%s', which is reserved " "on Windows") % c
if ord(c) <= 31:
return _("filename contains %r, which is invalid " "on Windows") % c
base = n.split(".")[0]
if base and base.lower() in _winreservednames:
return _("filename contains '%s', which is reserved " "on Windows") % base
t = n[-1:]
if t in ". " and n not in "..":
return _("filename ends with '%s', which is not allowed " "on Windows") % t