mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1290040 - Make find_program return short paths automatically when paths contain spaces on Windows. r=gps
Also fake enough of ctypes to keep the configure unit tests passing after these changes.
This commit is contained in:
parent
c2df8cd611
commit
da40819e21
@ -61,6 +61,49 @@ def is_absolute_or_relative(path):
|
||||
def normsep(path):
|
||||
return mozpath.normsep(path)
|
||||
|
||||
|
||||
@imports('ctypes')
|
||||
@imports(_from='ctypes', _import='wintypes')
|
||||
def get_GetShortPathNameW():
|
||||
GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
|
||||
GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR,
|
||||
wintypes.DWORD]
|
||||
GetShortPathNameW.restype = wintypes.DWORD
|
||||
return GetShortPathNameW
|
||||
|
||||
|
||||
@template
|
||||
@imports('ctypes')
|
||||
@imports('platform')
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def normalize_path():
|
||||
# Until the build system can properly handle programs that need quoting,
|
||||
# transform those paths into their short version on Windows (e.g.
|
||||
# c:\PROGRA~1...).
|
||||
if platform.system() == 'Windows':
|
||||
GetShortPathNameW = get_GetShortPathNameW()
|
||||
|
||||
def normalize_path(path):
|
||||
path = normsep(path)
|
||||
if quote(path) == path:
|
||||
return path
|
||||
size = 0
|
||||
while True:
|
||||
out = ctypes.create_unicode_buffer(size)
|
||||
needed = GetShortPathNameW(path, out, size)
|
||||
if size >= needed:
|
||||
return normsep(out.value)
|
||||
size = needed
|
||||
|
||||
else:
|
||||
def normalize_path(path):
|
||||
return normsep(path)
|
||||
|
||||
return normalize_path
|
||||
|
||||
normalize_path = normalize_path()
|
||||
|
||||
|
||||
# Locates the given program using which, or returns the given path if it
|
||||
# exists.
|
||||
# The `paths` parameter may be passed to search the given paths instead of
|
||||
@ -72,15 +115,15 @@ def normsep(path):
|
||||
def find_program(file, paths=None):
|
||||
try:
|
||||
if is_absolute_or_relative(file):
|
||||
return normsep(which(os.path.basename(file),
|
||||
[os.path.dirname(file)]))
|
||||
return normalize_path(which(os.path.basename(file),
|
||||
[os.path.dirname(file)]))
|
||||
if paths:
|
||||
if not isinstance(paths, (list, tuple)):
|
||||
die("Paths provided to find_program must be a list of strings, "
|
||||
"not %r", paths)
|
||||
paths = list(itertools.chain(
|
||||
*(p.split(pathsep) for p in paths if p)))
|
||||
return normsep(which(file, path=paths))
|
||||
return normalize_path(which(file, path=paths))
|
||||
except WhichError:
|
||||
return None
|
||||
|
||||
|
@ -120,8 +120,44 @@ class ConfigureTestSandbox(ConfigureSandbox):
|
||||
if what == 'os.environ':
|
||||
return self._environ
|
||||
|
||||
if what == 'ctypes.wintypes':
|
||||
return ReadOnlyNamespace(
|
||||
LPCWSTR=0,
|
||||
LPWSTR=1,
|
||||
DWORD=2,
|
||||
)
|
||||
|
||||
if what == 'ctypes':
|
||||
class CTypesFunc(object):
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self._func(*args, **kwargs)
|
||||
|
||||
|
||||
return ReadOnlyNamespace(
|
||||
create_unicode_buffer=self.create_unicode_buffer,
|
||||
windll=ReadOnlyNamespace(
|
||||
kernel32=ReadOnlyNamespace(
|
||||
GetShortPathNameW=CTypesFunc(self.GetShortPathNameW),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
return super(ConfigureTestSandbox, self)._get_one_import(what)
|
||||
|
||||
def create_unicode_buffer(self, *args, **kwargs):
|
||||
class Buffer(object):
|
||||
def __init__(self):
|
||||
self.value = ''
|
||||
|
||||
return Buffer()
|
||||
|
||||
def GetShortPathNameW(self, path_in, path_out, length):
|
||||
path_out.value = path_in
|
||||
return length
|
||||
|
||||
def which(self, command, path=None):
|
||||
for parent in (path or self._search_path):
|
||||
c = mozpath.abspath(mozpath.join(parent, command))
|
||||
|
Loading…
Reference in New Issue
Block a user