2016-11-19 21:01:44 +00:00
|
|
|
import os
|
2018-08-11 13:11:04 +00:00
|
|
|
import sys
|
2019-02-05 11:53:49 +00:00
|
|
|
import shlex
|
2016-11-07 21:17:39 +00:00
|
|
|
import shutil
|
2019-02-05 11:53:49 +00:00
|
|
|
import argparse
|
|
|
|
import platform
|
2016-10-10 23:14:50 +00:00
|
|
|
import subprocess
|
2019-08-03 02:22:16 +00:00
|
|
|
import uuid
|
2016-10-10 23:14:50 +00:00
|
|
|
|
2016-11-19 21:01:44 +00:00
|
|
|
|
|
|
|
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
|
|
|
|
2019-11-11 11:41:23 +00:00
|
|
|
if os.name == 'nt':
|
2019-04-15 10:04:44 +00:00
|
|
|
import ctypes
|
|
|
|
from ctypes import wintypes
|
|
|
|
_GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
|
|
|
|
_GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD]
|
|
|
|
_GetShortPathNameW.restype = wintypes.DWORD
|
|
|
|
|
|
|
|
def win32_get_short_path_name(long_name):
|
|
|
|
"""
|
|
|
|
Gets the short path name of a given long path.
|
|
|
|
http://stackoverflow.com/a/23598461/200291
|
|
|
|
"""
|
|
|
|
output_buf_size = 0
|
|
|
|
while True:
|
|
|
|
output_buf = ctypes.create_unicode_buffer(output_buf_size)
|
|
|
|
needed = _GetShortPathNameW(long_name, output_buf, output_buf_size)
|
|
|
|
if output_buf_size >= needed:
|
|
|
|
return output_buf.value
|
|
|
|
else:
|
|
|
|
output_buf_size = needed
|
|
|
|
|
2019-08-03 02:22:16 +00:00
|
|
|
|
|
|
|
def get_wine_shortpath(winecmd, wine_paths):
|
|
|
|
seen = set()
|
|
|
|
wine_paths += [p for p in wine_paths if not (p in seen or seen.add(p))]
|
|
|
|
|
|
|
|
getShortPathScript = '%s.bat' % str(uuid.uuid4()).lower()[:5]
|
|
|
|
with open(getShortPathScript, mode='w') as f:
|
|
|
|
f.write("@ECHO OFF\nfor %%x in (%*) do (\n echo|set /p=;%~sx\n)\n")
|
|
|
|
f.flush()
|
|
|
|
try:
|
|
|
|
with open(os.devnull, 'w') as stderr:
|
|
|
|
wine_path = subprocess.check_output(
|
|
|
|
winecmd +
|
|
|
|
['cmd', '/C', getShortPathScript] + wine_paths,
|
|
|
|
stderr=stderr).decode('utf-8')
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
print("Could not get short paths: %s" % e)
|
|
|
|
wine_path = ';'.join(wine_paths)
|
|
|
|
finally:
|
|
|
|
os.remove(getShortPathScript)
|
|
|
|
if len(wine_path) > 2048:
|
|
|
|
raise AssertionError('WINEPATH size {} > 2048'
|
|
|
|
' this will cause random failure.'.format(
|
|
|
|
len(wine_path)))
|
|
|
|
return wine_path
|
|
|
|
|
|
|
|
|
2016-10-10 23:14:50 +00:00
|
|
|
class Colors:
|
|
|
|
HEADER = '\033[95m'
|
|
|
|
OKBLUE = '\033[94m'
|
|
|
|
OKGREEN = '\033[92m'
|
|
|
|
WARNING = '\033[93m'
|
|
|
|
FAIL = '\033[91m'
|
|
|
|
ENDC = '\033[0m'
|
|
|
|
|
|
|
|
force_disable = False
|
|
|
|
|
2019-02-05 11:53:49 +00:00
|
|
|
def _windows_ansi():
|
|
|
|
from ctypes import windll, byref
|
|
|
|
from ctypes.wintypes import DWORD
|
|
|
|
|
|
|
|
kernel = windll.kernel32
|
|
|
|
stdout = kernel.GetStdHandle(-11)
|
|
|
|
mode = DWORD()
|
|
|
|
if not kernel.GetConsoleMode(stdout, byref(mode)):
|
|
|
|
return False
|
|
|
|
# Try setting ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4)
|
|
|
|
# If that fails (returns 0), we disable colors
|
|
|
|
return kernel.SetConsoleMode(stdout, mode.value | 0x4) or os.environ.get('ANSICON')
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def can_enable(cls):
|
|
|
|
if not os.isatty(sys.stdout.fileno()):
|
|
|
|
return False
|
|
|
|
if platform.system().lower() == 'windows':
|
|
|
|
return cls._windows_ansi()
|
|
|
|
return os.environ.get('TERM') != 'dumb'
|
|
|
|
|
2016-10-10 23:14:50 +00:00
|
|
|
@classmethod
|
|
|
|
def disable(cls):
|
|
|
|
cls.HEADER = ''
|
|
|
|
cls.OKBLUE = ''
|
|
|
|
cls.OKGREEN = ''
|
|
|
|
cls.WARNING = ''
|
|
|
|
cls.FAIL = ''
|
|
|
|
cls.ENDC = ''
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def enable(cls):
|
|
|
|
if cls.force_disable:
|
|
|
|
return
|
|
|
|
|
|
|
|
cls.HEADER = '\033[95m'
|
|
|
|
cls.OKBLUE = '\033[94m'
|
|
|
|
cls.OKGREEN = '\033[92m'
|
|
|
|
cls.WARNING = '\033[93m'
|
|
|
|
cls.FAIL = '\033[91m'
|
|
|
|
cls.ENDC = '\033[0m'
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-04-08 09:51:07 +00:00
|
|
|
def git(*args, repository_path='.', fatal=True):
|
|
|
|
try:
|
|
|
|
ret = subprocess.check_output(["git"] + list(args), cwd=repository_path,
|
|
|
|
stdin=subprocess.DEVNULL,
|
|
|
|
stderr=subprocess.STDOUT).decode()
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
if fatal:
|
|
|
|
raise e
|
|
|
|
print("Non-fatal error running git {}:\n{}".format(' '.join(args), e))
|
|
|
|
return None
|
|
|
|
return ret
|
2016-11-07 21:17:39 +00:00
|
|
|
|
|
|
|
def accept_command(commands):
|
2017-01-03 17:23:18 +00:00
|
|
|
"""Search @commands and returns the first found absolute path."""
|
2016-11-07 21:17:39 +00:00
|
|
|
for command in commands:
|
2017-01-03 17:23:18 +00:00
|
|
|
command = shutil.which(command)
|
|
|
|
if command:
|
2016-11-07 21:17:39 +00:00
|
|
|
return command
|
|
|
|
return None
|
2016-11-19 21:01:44 +00:00
|
|
|
|
|
|
|
def get_meson():
|
|
|
|
meson = os.path.join(ROOTDIR, 'meson', 'meson.py')
|
|
|
|
if os.path.exists(meson):
|
2018-08-10 21:20:14 +00:00
|
|
|
return [sys.executable, meson]
|
2017-12-18 15:55:11 +00:00
|
|
|
|
2017-12-18 17:46:14 +00:00
|
|
|
mesonintrospect = os.environ.get('MESONINTROSPECT', '')
|
|
|
|
for comp in shlex.split (mesonintrospect):
|
|
|
|
# mesonintrospect might look like "/usr/bin/python /somewhere/meson introspect",
|
|
|
|
# let's not get tricked
|
|
|
|
if 'python' in os.path.basename (comp):
|
|
|
|
continue
|
2018-08-10 21:20:14 +00:00
|
|
|
if os.path.exists(comp):
|
|
|
|
if comp.endswith('.py'):
|
|
|
|
return [sys.executable, comp]
|
2017-12-18 17:46:14 +00:00
|
|
|
else:
|
2018-08-10 21:20:14 +00:00
|
|
|
return [comp]
|
|
|
|
|
|
|
|
meson = accept_command(['meson.py'])
|
|
|
|
if meson:
|
|
|
|
return [sys.executable, meson]
|
|
|
|
meson = accept_command(['meson'])
|
|
|
|
if meson:
|
|
|
|
return [meson]
|
|
|
|
raise RuntimeError('Could not find Meson')
|