Browse Source

Intermediate changes

robot-piglet 6 months ago
parent
commit
1ca193d726

+ 1 - 1
contrib/python/argcomplete/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: argcomplete
-Version: 3.4.0
+Version: 3.5.0
 Summary: Bash tab completion for argparse
 Home-page: https://github.com/kislyuk/argcomplete
 Author: Andrey Kislyuk

+ 4 - 0
contrib/python/argcomplete/py3/.dist-info/entry_points.txt

@@ -0,0 +1,4 @@
+[console_scripts]
+activate-global-python-argcomplete = argcomplete.scripts.activate_global_python_argcomplete:main
+python-argcomplete-check-easy-install-script = argcomplete.scripts.python_argcomplete_check_easy_install_script:main
+register-python-argcomplete = argcomplete.scripts.register_python_argcomplete:main

+ 1 - 0
contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete

@@ -1,5 +1,6 @@
 #compdef -default-
 
+# argcomplete global completion loader for zsh and bash
 # Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
 # Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
 

+ 1 - 1
contrib/python/argcomplete/py3/argcomplete/completers.py

@@ -22,7 +22,7 @@ class BaseCompleter:
 
     def __call__(
         self, *, prefix: str, action: argparse.Action, parser: argparse.ArgumentParser, parsed_args: argparse.Namespace
-    ):
+    ) -> None:
         raise NotImplementedError("This method should be implemented by a subclass.")
 
 

+ 7 - 5
contrib/python/argcomplete/py3/argcomplete/finders.py

@@ -7,10 +7,10 @@ import argparse
 import os
 import sys
 from collections.abc import Mapping
-from typing import Callable, Dict, List, Optional, Sequence, Union
+from typing import Callable, Dict, List, Optional, Sequence, TextIO, Union
 
 from . import io as _io
-from .completers import ChoicesCompleter, FilesCompleter, SuppressCompleter
+from .completers import BaseCompleter, ChoicesCompleter, FilesCompleter, SuppressCompleter
 from .io import debug, mute_stderr
 from .lexers import split_line
 from .packages._argparse import IntrospectiveArgumentParser, action_is_greedy, action_is_open, action_is_satisfied
@@ -66,13 +66,13 @@ class CompletionFinder(object):
         argument_parser: argparse.ArgumentParser,
         always_complete_options: Union[bool, str] = True,
         exit_method: Callable = os._exit,
-        output_stream=None,
+        output_stream: Optional[TextIO] = None,
         exclude: Optional[Sequence[str]] = None,
         validator: Optional[Callable] = None,
         print_suppressed: bool = False,
         append_space: Optional[bool] = None,
-        default_completer=FilesCompleter(),
-    ):
+        default_completer: BaseCompleter = FilesCompleter(),
+    ) -> None:
         """
         :param argument_parser: The argument parser to autocomplete on
         :param always_complete_options:
@@ -132,6 +132,8 @@ class CompletionFinder(object):
                 debug("Unable to open fd 8 for writing, quitting")
                 exit_method(1)
 
+        assert output_stream is not None
+
         ifs = os.environ.get("_ARGCOMPLETE_IFS", "\013")
         if len(ifs) != 1:
             debug("Invalid value for IFS, quitting [{v}]".format(v=ifs))

+ 0 - 0
contrib/python/argcomplete/py3/argcomplete/scripts/__init__.py


+ 168 - 0
contrib/python/argcomplete/py3/argcomplete/scripts/activate_global_python_argcomplete.py

@@ -0,0 +1,168 @@
+#!/usr/bin/env python3
+# PYTHON_ARGCOMPLETE_OK
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+Activate the generic bash-completion script or zsh completion autoload function for the argcomplete module.
+"""
+
+import argparse
+import os
+import shutil
+import site
+import subprocess
+import sys
+
+import argcomplete
+
+# PEP 366
+__package__ = "argcomplete.scripts"
+
+zsh_shellcode = """
+# Begin added by argcomplete
+fpath=( {zsh_fpath} "${{fpath[@]}}" )
+# End added by argcomplete
+"""
+
+bash_shellcode = """
+# Begin added by argcomplete
+source "{activator}"
+# End added by argcomplete
+"""
+
+parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+parser.add_argument("-y", "--yes", help="automatically answer yes for all questions", action="store_true")
+parser.add_argument("--dest", help='Specify the shell completion modules directory to install into, or "-" for stdout')
+parser.add_argument("--user", help="Install into user directory", action="store_true")
+argcomplete.autocomplete(parser)
+args = None
+
+
+def get_local_dir():
+    try:
+        return subprocess.check_output(["brew", "--prefix"]).decode().strip()
+    except (FileNotFoundError, subprocess.CalledProcessError):
+        return "/usr/local"
+
+
+def get_zsh_system_dir():
+    return f"{get_local_dir()}/share/zsh/site-functions"
+
+
+def get_bash_system_dir():
+    if "BASH_COMPLETION_COMPAT_DIR" in os.environ:
+        return os.environ["BASH_COMPLETION_COMPAT_DIR"]
+    elif sys.platform == "darwin":
+        return f"{get_local_dir()}/etc/bash_completion.d"  # created by homebrew
+    else:
+        return "/etc/bash_completion.d"  # created by bash-completion
+
+
+def get_activator_dir():
+    return os.path.join(os.path.abspath(os.path.dirname(argcomplete.__file__)), "bash_completion.d")
+
+
+def get_activator_path():
+    return os.path.join(get_activator_dir(), "_python-argcomplete")
+
+
+def install_to_destination(dest):
+    activator = get_activator_path()
+    if dest == "-":
+        with open(activator) as fh:
+            sys.stdout.write(fh.read())
+        return
+    destdir = os.path.dirname(dest)
+    if not os.path.exists(destdir):
+        try:
+            os.makedirs(destdir, exist_ok=True)
+        except Exception as e:
+            parser.error(f"path {destdir} does not exist and could not be created: {e}")
+    try:
+        print(f"Installing {activator} to {dest}...", file=sys.stderr)
+        shutil.copy(activator, dest)
+        print("Installed.", file=sys.stderr)
+    except Exception as e:
+        parser.error(
+            f"while installing to {dest}: {e}. Please run this command using sudo, or see --help for more options."
+        )
+
+
+def get_consent():
+    assert args is not None
+    if args.yes is True:
+        return True
+    while True:
+        res = input("OK to proceed? [y/n] ")
+        if res.lower() not in {"y", "n", "yes", "no"}:
+            print('Please answer "yes" or "no".', file=sys.stderr)
+        elif res.lower() in {"y", "yes"}:
+            return True
+        else:
+            return False
+
+
+def append_to_config_file(path, shellcode):
+    if os.path.exists(path):
+        with open(path, 'r') as fh:
+            if shellcode in fh.read():
+                print(f"The code already exists in the file {path}.", file=sys.stderr)
+                return
+        print(f"argcomplete needs to append to the file {path}. The following code will be appended:", file=sys.stderr)
+        for line in shellcode.splitlines():
+            print(">", line, file=sys.stderr)
+        if not get_consent():
+            print("Not added.", file=sys.stderr)
+            return
+    print(f"Adding shellcode to {path}...", file=sys.stderr)
+    with open(path, "a") as fh:
+        fh.write(shellcode)
+    print("Added.", file=sys.stderr)
+
+
+def link_user_rcfiles():
+    # TODO: warn if running as superuser
+    zsh_rcfile = os.path.join(os.path.expanduser(os.environ.get("ZDOTDIR", "~")), ".zshenv")
+    append_to_config_file(zsh_rcfile, zsh_shellcode.format(zsh_fpath=get_activator_dir()))
+
+    bash_completion_user_file = os.path.expanduser("~/.bash_completion")
+    append_to_config_file(bash_completion_user_file, bash_shellcode.format(activator=get_activator_path()))
+
+
+def main():
+    global args
+    args = parser.parse_args()
+
+    destinations = []
+
+    if args.dest:
+        if args.dest != "-" and not os.path.exists(args.dest):
+            parser.error(f"directory {args.dest} was specified via --dest, but it does not exist")
+        destinations.append(args.dest)
+    elif site.ENABLE_USER_SITE and site.USER_SITE and site.USER_SITE in argcomplete.__file__:
+        print(
+            "Argcomplete was installed in the user site local directory. Defaulting to user installation.",
+            file=sys.stderr,
+        )
+        link_user_rcfiles()
+    elif sys.prefix != sys.base_prefix:
+        print("Argcomplete was installed in a virtual environment. Defaulting to user installation.", file=sys.stderr)
+        link_user_rcfiles()
+    elif args.user:
+        link_user_rcfiles()
+    else:
+        print("Defaulting to system-wide installation.", file=sys.stderr)
+        destinations.append(f"{get_zsh_system_dir()}/_python-argcomplete")
+        destinations.append(f"{get_bash_system_dir()}/python-argcomplete")
+
+    for destination in destinations:
+        install_to_destination(destination)
+
+    if args.dest is None:
+        print("Please restart your shell or source the installed file to activate it.", file=sys.stderr)
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 84 - 0
contrib/python/argcomplete/py3/argcomplete/scripts/python_argcomplete_check_easy_install_script.py

@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+This script is part of the Python argcomplete package (https://github.com/kislyuk/argcomplete).
+It is used to check if an EASY-INSTALL-SCRIPT wrapper redirects to a script that contains the string
+"PYTHON_ARGCOMPLETE_OK". If you have enabled global completion in argcomplete, the completion hook will run it every
+time you press <TAB> in your shell.
+
+Usage:
+    python-argcomplete-check-easy-install-script <input executable file>
+"""
+
+import sys
+
+# PEP 366
+__package__ = "argcomplete.scripts"
+
+
+def main():
+    if len(sys.argv) != 2:
+        sys.exit(__doc__)
+
+    sys.tracebacklimit = 0
+
+    with open(sys.argv[1]) as fh:
+        line1, head = fh.read(1024).split("\n", 1)[:2]
+        if line1.startswith("#") and ("py" in line1 or "Py" in line1):
+            import re
+
+            lines = head.split("\n", 12)
+            for line in lines:
+                if line.startswith("# EASY-INSTALL-SCRIPT"):
+                    import pkg_resources
+
+                    re_match = re.match("# EASY-INSTALL-SCRIPT: '(.+)','(.+)'", line)
+                    assert re_match is not None
+                    dist, script = re_match.groups()
+                    if "PYTHON_ARGCOMPLETE_OK" in pkg_resources.get_distribution(dist).get_metadata(
+                        "scripts/" + script
+                    ):
+                        return 0
+                elif line.startswith("# EASY-INSTALL-ENTRY-SCRIPT"):
+                    re_match = re.match("# EASY-INSTALL-ENTRY-SCRIPT: '(.+)','(.+)','(.+)'", line)
+                    assert re_match is not None
+                    dist, group, name = re_match.groups()
+                    import pkgutil
+
+                    import pkg_resources
+
+                    entry_point_info = pkg_resources.get_distribution(dist).get_entry_info(group, name)
+                    assert entry_point_info is not None
+                    module_name = entry_point_info.module_name
+                    with open(pkgutil.get_loader(module_name).get_filename()) as mod_fh:  # type: ignore
+                        if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+                            return 0
+                elif line.startswith("# EASY-INSTALL-DEV-SCRIPT"):
+                    for line2 in lines:
+                        if line2.startswith("__file__"):
+                            re_match = re.match("__file__ = '(.+)'", line2)
+                            assert re_match is not None
+                            filename = re_match.group(1)
+                            with open(filename) as mod_fh:
+                                if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+                                    return 0
+                elif line.startswith("# PBR Generated"):
+                    re_match = re.search("from (.*) import", head)
+                    assert re_match is not None
+                    module = re_match.groups()[0]
+                    import pkgutil
+
+                    import pkg_resources
+
+                    with open(pkgutil.get_loader(module).get_filename()) as mod_fh:  # type: ignore
+                        if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+                            return 0
+
+    return 1
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 79 - 0
contrib/python/argcomplete/py3/argcomplete/scripts/register_python_argcomplete.py

@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+# PYTHON_ARGCOMPLETE_OK
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+Register a Python executable for use with the argcomplete module.
+
+To perform the registration, source the output of this script in your bash shell
+(quote the output to avoid interpolation).
+
+Example:
+
+    $ eval "$(register-python-argcomplete my-favorite-script.py)"
+
+For Tcsh
+
+    $ eval `register-python-argcomplete --shell tcsh my-favorite-script.py`
+
+For Fish
+
+    $ register-python-argcomplete --shell fish my-favourite-script.py > ~/.config/fish/my-favourite-script.py.fish
+"""
+
+import argparse
+import sys
+
+import argcomplete
+
+# PEP 366
+__package__ = "argcomplete.scripts"
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+
+    parser.add_argument(
+        "--no-defaults",
+        dest="use_defaults",
+        action="store_false",
+        default=True,
+        help="when no matches are generated, do not fallback to readline's default completion (affects bash only)",
+    )
+    parser.add_argument(
+        "--complete-arguments",
+        nargs=argparse.REMAINDER,
+        help="arguments to call complete with; use of this option discards default options (affects bash only)",
+    )
+    parser.add_argument(
+        "-s",
+        "--shell",
+        choices=("bash", "zsh", "tcsh", "fish", "powershell"),
+        default="bash",
+        help="output code for the specified shell",
+    )
+    parser.add_argument(
+        "-e", "--external-argcomplete-script", help="external argcomplete script for auto completion of the executable"
+    )
+
+    parser.add_argument("executable", nargs="+", help="executable to completed (when invoked by exactly this name)")
+
+    argcomplete.autocomplete(parser)
+
+    if len(sys.argv) == 1:
+        parser.print_help()
+        sys.exit(1)
+
+    args = parser.parse_args()
+
+    sys.stdout.write(
+        argcomplete.shellcode(
+            args.executable, args.use_defaults, args.shell, args.complete_arguments, args.external_argcomplete_script
+        )
+    )
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 6 - 1
contrib/python/argcomplete/py3/ya.make

@@ -2,7 +2,7 @@
 
 PY3_LIBRARY()
 
-VERSION(3.4.0)
+VERSION(3.5.0)
 
 LICENSE(Apache-2.0)
 
@@ -21,12 +21,17 @@ PY_SRCS(
     argcomplete/packages/__init__.py
     argcomplete/packages/_argparse.py
     argcomplete/packages/_shlex.py
+    argcomplete/scripts/__init__.py
+    argcomplete/scripts/activate_global_python_argcomplete.py
+    argcomplete/scripts/python_argcomplete_check_easy_install_script.py
+    argcomplete/scripts/register_python_argcomplete.py
     argcomplete/shell_integration.py
 )
 
 RESOURCE_FILES(
     PREFIX contrib/python/argcomplete/py3/
     .dist-info/METADATA
+    .dist-info/entry_points.txt
     .dist-info/top_level.txt
     argcomplete/bash_completion.d/_python-argcomplete
     argcomplete/py.typed