Release 1.21.2
[platform/upstream/gstreamer.git] / scripts / common.py
1 import os
2 import sys
3 import shlex
4 import shutil
5 import argparse
6 import platform
7 import subprocess
8 import uuid
9
10
11 ROOTDIR = os.path.abspath(os.path.dirname(__file__))
12
13
14 if os.name == 'nt':
15     import ctypes
16     from ctypes import wintypes
17     _GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
18     _GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD]
19     _GetShortPathNameW.restype = wintypes.DWORD
20
21 def win32_get_short_path_name(long_name):
22     """
23     Gets the short path name of a given long path.
24     http://stackoverflow.com/a/23598461/200291
25     """
26     output_buf_size = 0
27     while True:
28         output_buf = ctypes.create_unicode_buffer(output_buf_size)
29         needed = _GetShortPathNameW(long_name, output_buf, output_buf_size)
30         if output_buf_size >= needed:
31             return output_buf.value
32         else:
33             output_buf_size = needed
34
35
36 def get_wine_shortpath(winecmd, wine_paths):
37     seen = set()
38     wine_paths += [p for p in wine_paths if not (p in seen or seen.add(p))]
39
40     getShortPathScript = '%s.bat' % str(uuid.uuid4()).lower()[:5]
41     with open(getShortPathScript, mode='w') as f:
42         f.write("@ECHO OFF\nfor %%x in (%*) do (\n echo|set /p=;%~sx\n)\n")
43         f.flush()
44     try:
45         with open(os.devnull, 'w') as stderr:
46             wine_path = subprocess.check_output(
47                 winecmd +
48                 ['cmd', '/C', getShortPathScript] + wine_paths,
49                 stderr=stderr).decode('utf-8')
50     except subprocess.CalledProcessError as e:
51         print("Could not get short paths: %s" % e)
52         wine_path = ';'.join(wine_paths)
53     finally:
54         os.remove(getShortPathScript)
55     if len(wine_path) > 2048:
56         raise AssertionError('WINEPATH size {} > 2048'
57                                 ' this will cause random failure.'.format(
58                                     len(wine_path)))
59     return wine_path
60
61
62 class Colors:
63     HEADER = '\033[95m'
64     OKBLUE = '\033[94m'
65     OKGREEN = '\033[92m'
66     WARNING = '\033[93m'
67     FAIL = '\033[91m'
68     ENDC = '\033[0m'
69
70     force_disable = False
71
72     def _windows_ansi():
73         from ctypes import windll, byref
74         from ctypes.wintypes import DWORD
75
76         kernel = windll.kernel32
77         stdout = kernel.GetStdHandle(-11)
78         mode = DWORD()
79         if not kernel.GetConsoleMode(stdout, byref(mode)):
80             return False
81         # Try setting ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4)
82         # If that fails (returns 0), we disable colors
83         return kernel.SetConsoleMode(stdout, mode.value | 0x4) or os.environ.get('ANSICON')
84
85     @classmethod
86     def can_enable(cls):
87         if not os.isatty(sys.stdout.fileno()):
88             return False
89         if platform.system().lower() == 'windows':
90             return cls._windows_ansi()
91         return os.environ.get('TERM') != 'dumb'
92
93     @classmethod
94     def disable(cls):
95         cls.HEADER = ''
96         cls.OKBLUE = ''
97         cls.OKGREEN = ''
98         cls.WARNING = ''
99         cls.FAIL = ''
100         cls.ENDC = ''
101
102     @classmethod
103     def enable(cls):
104         if cls.force_disable:
105             return
106
107         cls.HEADER = '\033[95m'
108         cls.OKBLUE = '\033[94m'
109         cls.OKGREEN = '\033[92m'
110         cls.WARNING = '\033[93m'
111         cls.FAIL = '\033[91m'
112         cls.ENDC = '\033[0m'
113
114
115
116 def git(*args, repository_path='.', fatal=True):
117     try:
118         ret = subprocess.check_output(["git"] + list(args), cwd=repository_path,
119                                       stdin=subprocess.DEVNULL,
120                                       stderr=subprocess.STDOUT).decode()
121     except subprocess.CalledProcessError as e:
122         if fatal:
123             raise e
124         print("Non-fatal error running git {}:\n{}".format(' '.join(args), e))
125         return None
126     return ret
127
128 def accept_command(commands):
129     """Search @commands and returns the first found absolute path."""
130     for command in commands:
131         command = shutil.which(command)
132         if command:
133             return command
134     return None
135
136 def get_meson():
137     meson = os.path.join(ROOTDIR, 'meson', 'meson.py')
138     if os.path.exists(meson):
139         return [sys.executable, meson]
140
141     mesonintrospect = os.environ.get('MESONINTROSPECT', '')
142     for comp in shlex.split (mesonintrospect):
143         # mesonintrospect might look like "/usr/bin/python /somewhere/meson introspect",
144         # let's not get tricked
145         if 'python' in os.path.basename (comp):
146             continue
147         if os.path.exists(comp):
148             if comp.endswith('.py'):
149                 return [sys.executable, comp]
150             else:
151                 return [comp]
152
153     meson = accept_command(['meson.py'])
154     if meson:
155         return [sys.executable, meson]
156     meson = accept_command(['meson'])
157     if meson:
158         return [meson]
159     raise RuntimeError('Could not find Meson')