subprojects: update glib-networking to 2.74.0 and switch to file wrap
[platform/upstream/gstreamer.git] / gst-env.py
index 6383910..fb266ad 100755 (executable)
@@ -1,25 +1,22 @@
 #!/usr/bin/env python3
 
 import argparse
-import contextlib
 import glob
 import json
 import os
 import platform
 import re
-import site
 import shlex
 import shutil
 import subprocess
-import sys
 import tempfile
 import pathlib
 import signal
 from functools import lru_cache
 from pathlib import PurePath, Path
+from sys import exit
 
-from distutils.sysconfig import get_python_lib
-from distutils.util import strtobool
+from typing import Any
 
 from scripts.common import get_meson
 from scripts.common import git
@@ -43,7 +40,7 @@ SHAREDLIB_REG = re.compile(r'\.so|\.dylib|\.dll')
 GSTPLUGIN_FILEPATH_REG_TEMPLATE = r'.*/{libdir}/gstreamer-1.0/[^/]+$'
 GSTPLUGIN_FILEPATH_REG = None
 
-BC_RC =  '''
+BC_RC = '''
 BASH_COMPLETION_SCRIPTS="{bash_completions}"
 BASH_COMPLETION_PATHS="{bash_completions_paths}"
 for p in $BASH_COMPLETION_PATHS; do
@@ -55,6 +52,16 @@ done
 BASH_COMPLETION_PATHS = [SCRIPTDIR + '/subprojects/gstreamer/data/bash-completion/completions']
 BASH_COMPLETION_PATHS += [SCRIPTDIR + '/subprojects/gst-devtools/validate/data/bash-completion/completions']
 
+
+def str_to_bool(value: Any) -> bool:
+    """Return whether the provided string (or any value really) represents true. Otherwise false.
+    Just like plugin server stringToBoolean.
+    """
+    if not value:
+        return False
+    return str(value).lower() in ("y", "yes", "t", "true", "on", "1")
+
+
 def listify(o):
     if isinstance(o, str):
         return [o]
@@ -62,6 +69,7 @@ def listify(o):
         return o
     raise AssertionError('Object {!r} must be a string or a list'.format(o))
 
+
 def stringify(o):
     if isinstance(o, str):
         return o
@@ -71,6 +79,7 @@ def stringify(o):
         raise AssertionError('Did not expect object {!r} to have more than one element'.format(o))
     raise AssertionError('Object {!r} must be a string or a list'.format(o))
 
+
 def prepend_env_var(env, var, value, sysroot):
     if var is None:
         return
@@ -87,6 +96,7 @@ def prepend_env_var(env, var, value, sysroot):
     env[var] = val + env_val
     env[var] = env[var].replace(os.pathsep + os.pathsep, os.pathsep).strip(os.pathsep)
 
+
 def get_target_install_filename(target, filename):
     '''
     Checks whether this file is one of the files installed by the target
@@ -97,6 +107,7 @@ def get_target_install_filename(target, filename):
             return install_filename
     return None
 
+
 def get_pkgconfig_variable_from_pcfile(pcfile, varname):
     variables = {}
     substre = re.compile('\$\{[^${}]+\}')
@@ -114,6 +125,7 @@ def get_pkgconfig_variable_from_pcfile(pcfile, varname):
             variables[key] = value
     return variables.get(varname, '')
 
+
 @lru_cache()
 def get_pkgconfig_variable(builddir, pcname, varname):
     '''
@@ -138,6 +150,7 @@ def is_gio_module(target, filename, builddir):
         return False
     return True
 
+
 def is_library_target_and_not_plugin(target, filename):
     '''
     Don't add plugins to PATH/LD_LIBRARY_PATH because:
@@ -160,6 +173,7 @@ def is_library_target_and_not_plugin(target, filename):
         return False
     return True
 
+
 def is_binary_target_and_in_path(target, filename, bindir):
     if target['type'] != 'executable':
         return False
@@ -191,6 +205,7 @@ def get_wine_subprocess_env(options, env):
 
     return env
 
+
 def setup_gdb(options):
     python_paths = set()
 
@@ -233,32 +248,34 @@ def setup_gdb(options):
 
     return python_paths
 
-def is_bash_completion_available (options):
-    return  os.path.exists(os.path.join(options.builddir, 'subprojects/gstreamer/data/bash-completion/helpers/gst'))
+
+def is_bash_completion_available(options):
+    return os.path.exists(os.path.join(options.builddir, 'subprojects/gstreamer/data/bash-completion/helpers/gst'))
+
 
 def get_subprocess_env(options, gst_version):
     env = os.environ.copy()
 
     env["CURRENT_GST"] = os.path.normpath(SCRIPTDIR)
     env["GST_VERSION"] = gst_version
-    prepend_env_var (env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
+    prepend_env_var(env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
         "%s/subprojects/gst-devtools/validate/data/scenarios" % SCRIPTDIR),
         options.sysroot)
     env["GST_VALIDATE_PLUGIN_PATH"] = os.path.normpath(
         "%s/subprojects/gst-devtools/validate/plugins" % options.builddir)
-    prepend_env_var (env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
+    prepend_env_var(env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
         "%s/subprojects/gst-editing-services/tests/validate" % SCRIPTDIR),
         options.sysroot)
-    env["GST_ENV"] = 'gst-' + gst_version
+    env["GST_ENV"] = gst_version
     env["GST_REGISTRY"] = os.path.normpath(options.builddir + "/registry.dat")
     prepend_env_var(env, "PATH", os.path.normpath(
         "%s/subprojects/gst-devtools/validate/tools" % options.builddir),
         options.sysroot)
 
-    prepend_env_var (env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
+    prepend_env_var(env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
         "%s/subprojects/gst-examples/webrtc/check/validate/scenarios" %
         SCRIPTDIR), options.sysroot)
-    prepend_env_var (env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
+    prepend_env_var(env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
         "%s/subprojects/gst-examples/webrtc/check/validate/apps" %
         SCRIPTDIR), options.sysroot)
 
@@ -302,13 +319,17 @@ def get_subprocess_env(options, gst_version):
                     options.sysroot)
 
     # gst-indent
-    prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'gstreamer', 'tools'),
+    prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'scripts'),
                     options.sysroot)
 
     # tools: gst-launch-1.0, gst-inspect-1.0
     prepend_env_var(env, "PATH", os.path.join(options.builddir, 'subprojects',
                                               'gstreamer', 'tools'),
                     options.sysroot)
+    # plugin scanner and generator
+    prepend_env_var(env, "PATH", os.path.join(options.builddir, 'subprojects',
+                                              'gstreamer', 'docs'),
+                    options.sysroot)
     prepend_env_var(env, "PATH", os.path.join(options.builddir, 'subprojects',
                                               'gst-plugins-base', 'tools'),
                     options.sysroot)
@@ -370,10 +391,16 @@ def get_subprocess_env(options, gst_version):
                                 os.path.join(options.builddir, root),
                                 options.sysroot)
 
-    with open(os.path.join(options.gstbuilddir, 'GstPluginsPath.json')) as f:
-        for plugin_path in json.load(f):
-            prepend_env_var(env, 'GST_PLUGIN_PATH', plugin_path,
-                            options.sysroot)
+    # Search for the Plugin paths file either in the build directory root
+    # or check if gstreamer is a subproject of another project
+    for sub_directories in [[], ['subprojects', 'gstreamer']]:
+        plugin_paths = os.path.join(options.builddir, *sub_directories, 'GstPluginsPath.json')
+        if os.path.exists(plugin_paths):
+            with open(plugin_paths) as f:
+                for plugin_path in json.load(f):
+                    prepend_env_var(env, 'GST_PLUGIN_PATH', plugin_path,
+                                    options.sysroot)
+            break
 
     # Sort to iterate in a consistent order (`set`s and `hash`es are randomized)
     for p in sorted(paths):
@@ -386,11 +413,11 @@ def get_subprocess_env(options, gst_version):
     presets = set()
     encoding_targets = set()
     python_dirs = setup_gdb(options)
+    overrides_dirs = set()
     if '--installed' in subprocess.check_output(meson + ['introspect', '-h']).decode():
         installed_s = subprocess.check_output(meson + ['introspect', options.builddir, '--installed'])
         for path, installpath in json.loads(installed_s.decode()).items():
             installpath_parts = pathlib.Path(installpath).parts
-            path_parts = pathlib.Path(path).parts
 
             # We want to add all python modules to the PYTHONPATH
             # in a manner consistent with the way they would be imported:
@@ -406,7 +433,10 @@ def get_subprocess_env(options, gst_version):
             if 'site-packages' in installpath_parts:
                 install_subpath = os.path.join(*installpath_parts[installpath_parts.index('site-packages') + 1:])
                 if path.endswith(install_subpath):
-                    python_dirs.add(path[:len (install_subpath) * -1])
+                    if os.path.commonprefix(["gi/overrides", install_subpath]):
+                        overrides_dirs.add(os.path.dirname(path))
+                    else:
+                        python_dirs.add(path[:len(install_subpath) * -1])
 
             if path.endswith('.prs'):
                 presets.add(os.path.dirname(path))
@@ -432,21 +462,28 @@ def get_subprocess_env(options, gst_version):
     for python_dir in sorted(python_dirs):
         prepend_env_var(env, 'PYTHONPATH', python_dir, options.sysroot)
 
+    for python_dir in sorted(overrides_dirs):
+        prepend_env_var(env, '_GI_OVERRIDES_PATH', python_dir, options.sysroot)
+
     mesonpath = os.path.join(SCRIPTDIR, "meson")
     if os.path.join(mesonpath):
         # Add meson/ into PYTHONPATH if we are using a local meson
         prepend_env_var(env, 'PYTHONPATH', mesonpath, options.sysroot)
 
+    # Ensure that gst-python/gi is used first
+    prepend_env_var(env, "PYTHONPATH", os.path.join(SCRIPTDIR, 'subprojects', 'gst-python'),
+                    options.sysroot)
+
     # For devhelp books
     if 'XDG_DATA_DIRS' not in env or not env['XDG_DATA_DIRS']:
         # Preserve default paths when empty
         prepend_env_var(env, 'XDG_DATA_DIRS', '/usr/local/share/:/usr/share/', '')
 
-    prepend_env_var (env, 'XDG_DATA_DIRS', os.path.join(options.builddir,
-                                                        'subprojects',
-                                                        'gst-docs',
-                                                        'GStreamer-doc'),
-                     options.sysroot)
+    prepend_env_var(env, 'XDG_DATA_DIRS', os.path.join(options.builddir,
+                                                       'subprojects',
+                                                       'gst-docs',
+                                                       'GStreamer-doc'),
+                    options.sysroot)
 
     if 'XDG_CONFIG_DIRS' not in env or not env['XDG_CONFIG_DIRS']:
         # Preserve default paths when empty
@@ -457,21 +494,20 @@ def get_subprocess_env(options, gst_version):
 
     return env
 
+
 def get_windows_shell():
-    command = ['powershell.exe' ,'-noprofile', '-executionpolicy', 'bypass', '-file',
+    command = ['powershell.exe''-noprofile', '-executionpolicy', 'bypass', '-file',
         os.path.join(SCRIPTDIR, 'data', 'misc', 'cmd_or_ps.ps1')]
     result = subprocess.check_output(command)
     return result.decode().strip()
 
+
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(prog="gst-env")
 
     parser.add_argument("--builddir",
                         default=DEFAULT_BUILDDIR,
                         help="The meson build directory")
-    parser.add_argument("--gstbuilddir",
-                        default=None,
-                        help="The meson GStreamer build directory (defaults to builddir)")
     parser.add_argument("--srcdir",
                         default=SCRIPTDIR,
                         help="The top level source directory")
@@ -494,16 +530,7 @@ if __name__ == "__main__":
         print("GStreamer not built in %s\n\nBuild it and try again" %
               options.builddir)
         exit(1)
-
-    if options.gstbuilddir and not os.path.exists(options.gstbuilddir):
-        print("GStreamer is not built in %s\n\nBuild it and try again" %
-              options.gstbuilddir)
-        exit(1)
-    elif not options.gstbuilddir:
-        options.gstbuilddir = options.builddir
-
     options.builddir = os.path.abspath(options.builddir)
-    options.gstbuilddir = os.path.abspath(options.gstbuilddir)
 
     if not os.path.exists(options.srcdir):
         print("The specified source dir does not exist" %
@@ -512,42 +539,49 @@ if __name__ == "__main__":
 
     # The following incantation will retrieve the current branch name.
     try:
-      gst_version = git("rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD",
-                        repository_path=options.srcdir).strip('\n')
+        gst_version = git("rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD",
+                          repository_path=options.srcdir).strip('\n')
     except subprocess.CalledProcessError:
-      gst_version = "unknown"
+        gst_version = "unknown"
 
     if options.wine:
         gst_version += '-' + os.path.basename(options.wine)
 
     env = get_subprocess_env(options, gst_version)
-    if not args:
-        if os.name == 'nt':
-            shell = get_windows_shell()
-            if shell == 'powershell.exe':
-                args = ['powershell.exe']
-                args += ['-NoLogo', '-NoExit']
-                prompt = 'function global:prompt {  "[gst-' + gst_version + '"+"] PS " + $PWD + "> "}'
-                args += ['-Command', prompt]
+    if os.name == 'nt':
+        shell = get_windows_shell()
+        if shell in ['powershell.exe', 'pwsh.exe']:
+            new_args = [shell, '-NoLogo']
+            if not args:
+                prompt = 'function global:prompt {  "[' + gst_version + '"+"] PS " + $PWD + "> "}'
+                new_args += ['-NoExit', '-Command', prompt]
             else:
-                args = [os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")]
-                args += ['/k', 'prompt [gst-{}] $P$G'.format(gst_version)]
+                new_args += ['-NonInteractive', '-Command'] + args
+            args = new_args
         else:
+            new_args = [os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")]
+            if not args:
+                new_args += ['/k', 'prompt [{}] $P$G'.format(gst_version)]
+            else:
+                new_args += ['/c', 'start', '/b', '/wait'] + args
+            args = new_args
+    if not args:
+        if os.name != 'nt':
             args = [os.environ.get("SHELL", os.path.realpath("/bin/sh"))]
-        if args[0].endswith('bash') and not strtobool(os.environ.get("GST_BUILD_DISABLE_PS1_OVERRIDE", r"FALSE")):
+        if args[0].endswith('bash') and not str_to_bool(os.environ.get("GST_BUILD_DISABLE_PS1_OVERRIDE", r"FALSE")):
             # Let the GC remove the tmp file
             tmprc = tempfile.NamedTemporaryFile(mode='w')
             bashrc = os.path.expanduser('~/.bashrc')
             if os.path.exists(bashrc):
                 with open(bashrc, 'r') as src:
                     shutil.copyfileobj(src, tmprc)
-            tmprc.write('\nexport PS1="[gst-%s] $PS1"' % gst_version)
+            tmprc.write('\nexport PS1="[%s] $PS1"' % gst_version)
             tmprc.flush()
             if is_bash_completion_available(options):
                 bash_completions_files = []
                 for p in BASH_COMPLETION_PATHS:
                     if os.path.exists(p):
-                        bash_completions_files +=  os.listdir(path=p)
+                        bash_completions_files += os.listdir(path=p)
                 bc_rc = BC_RC.format(bash_completions=' '.join(bash_completions_files), bash_completions_paths=' '.join(BASH_COMPLETION_PATHS))
                 tmprc.write(bc_rc)
                 tmprc.flush()
@@ -562,7 +596,7 @@ if __name__ == "__main__":
             args.append('--init-command')
             prompt_cmd = '''functions --copy fish_prompt original_fish_prompt
             function fish_prompt
-                echo -n '[gst-{}] '(original_fish_prompt)
+                echo -n '[{}] '(original_fish_prompt)
             end'''.format(gst_version)
             args.append(prompt_cmd)
         elif args[0].endswith('zsh'):
@@ -573,7 +607,7 @@ if __name__ == "__main__":
             if os.path.exists(zshrc):
                 with open(zshrc, 'r') as src:
                     shutil.copyfileobj(src, tmprc)
-            tmprc.write('\nexport PROMPT="[gst-{}] $PROMPT"'.format(gst_version))
+            tmprc.write('\nexport PROMPT="[{}] $PROMPT"'.format(gst_version))
             tmprc.flush()
             env['ZDOTDIR'] = tmpdir.name
     try:
@@ -582,6 +616,10 @@ if __name__ == "__main__":
                 print('{}={}'.format(name, shlex.quote(value)))
                 print('export {}'.format(name))
         else:
+            if os.environ.get("CI_PROJECT_NAME"):
+                print("Ignoring SIGINT when running on the CI,"
+                      " as we get spurious sigint in there for some reason.")
+                signal.signal(signal.SIGINT, signal.SIG_IGN)
             exit(subprocess.call(args, close_fds=False, env=env))
 
     except subprocess.CalledProcessError as e: