def _copy_vendor_libraries()

in mysql-connector-python/cpydist/__init__.py [0:0]


    def _copy_vendor_libraries(self):
        openssl_libs = []
        vendor_libs = []

        if os.name == "posix":
            # Bundle OpenSSL libs
            if self.with_openssl_lib_dir:
                libssl, libcrypto = self._get_openssl_libs()
                vendor_libs.append((self.with_openssl_lib_dir, [libssl, libcrypto]))
                # Copy libssl and libcrypto libraries to 'mysql/vendor/plugin' and
                # libcrypto to 'mysql/vendor/lib' on macOS
                if platform.system() == "Darwin":
                    vendor_libs.append(
                        (
                            self.with_openssl_lib_dir,
                            [
                                Path("plugin", libssl).as_posix(),
                                Path("plugin", libcrypto).as_posix(),
                            ],
                        )
                    )
                    vendor_libs.append(
                        (
                            self.with_openssl_lib_dir,
                            [
                                Path("lib", libcrypto).as_posix(),
                            ],
                        )
                    )

        # Plugins
        bundle_plugin_libs = False
        if self.with_mysql_capi:
            plugin_ext = "dll" if os.name == "nt" else "so"
            expected_plugin_paths = [
                ("lib", "plugin"),
                ("lib", "mysql", "plugin"),
                ("lib64", "mysql", "plugin"),
            ]
            plugin_path = ""
            for path in expected_plugin_paths:
                plugin_path = os.path.join(self.with_mysql_capi, *path)
                if os.path.exists(plugin_path):
                    self.log.info("plugin_path is set as : %s", plugin_path)
                    break
                plugin_path = ""

            if not len(plugin_path):
                searched_paths = ",".join(["/".join(p) for p in expected_plugin_paths])
                self.log.error(
                    "None of the expected authentication plugins directories exist : %s",
                    searched_paths,
                )
                raise FileNotFoundError(
                    f"None of the expected authentication plugins directories exist : {searched_paths}"
                )

            plugin_list = [
                ("LDAP", f"authentication_ldap_sasl_client.{plugin_ext}"),
                ("Kerberos", f"authentication_kerberos_client.{plugin_ext}"),
                ("OCI IAM", f"authentication_oci_client.{plugin_ext}"),
                ("WebAuthn", f"authentication_webauthn_client.{plugin_ext}"),
                (
                    "OpenID Connect",
                    f"authentication_openid_connect_client.{plugin_ext}",
                ),
                ("MySQL Native", f"mysql_native_password.{plugin_ext}"),
            ]

            for plugin_name, plugin_file in plugin_list:
                plugin_full_path = os.path.join(plugin_path, plugin_file)
                self.log.debug(
                    "%s plugin_path: '%s'",
                    plugin_name,
                    plugin_full_path,
                )
                if os.path.exists(plugin_full_path):
                    bundle_plugin_libs = True
                    vendor_libs.append(
                        (plugin_path, [os.path.join("plugin", plugin_file)])
                    )

            # vendor libraries
            if bundle_plugin_libs and os.name == "nt":
                plugin_libs = []
                libs_path = os.path.join(self.with_mysql_capi, "bin")
                for lib_name in ["libsasl.dll", "saslSCRAM.dll"]:
                    if os.path.exists(os.path.join(libs_path, lib_name)):
                        plugin_libs.append(lib_name)
                if plugin_libs:
                    vendor_libs.append((libs_path, plugin_libs))
                if self.with_openssl_lib_dir:
                    openssl_libs_path = os.path.abspath(self.with_openssl_lib_dir)
                    if os.path.basename(openssl_libs_path) == "lib":
                        openssl_libs_path = os.path.split(openssl_libs_path)[0]
                    if os.path.exists(openssl_libs_path) and os.path.exists(
                        os.path.join(openssl_libs_path, "bin")
                    ):
                        openssl_libs_path = os.path.join(openssl_libs_path, "bin")
                    print("# openssl_libs_path: %s", openssl_libs_path)
                else:
                    openssl_libs_path = os.path.join(self.with_mysql_capi, "bin")
                libssl, libcrypto = self._get_openssl_libs(openssl_libs_path, "dll")
                openssl_libs = [libssl, libcrypto]
                vendor_libs.append((openssl_libs_path, openssl_libs))

        if not vendor_libs:
            return

        self.log.debug("# vendor_libs: %s", vendor_libs)

        # mysql/vendor
        if not Path(self.vendor_folder).exists():
            Path(os.getcwd(), self.vendor_folder).mkdir(parents=True, exist_ok=True)

        # mysql/vendor/plugin
        if not Path(self.vendor_folder, "plugin").exists():
            Path(os.getcwd(), self.vendor_folder, "plugin").mkdir(
                parents=True, exist_ok=True
            )

        # mysql/vendor/private
        if not Path(self.vendor_folder, "private").exists():
            Path(os.getcwd(), self.vendor_folder, "private").mkdir(
                parents=True, exist_ok=True
            )

        # mysql/vendor/lib
        if (
            platform.system() == "Darwin"
            and not Path(self.vendor_folder, "lib").exists()
        ):
            Path(os.getcwd(), self.vendor_folder, "lib").mkdir(
                parents=True, exist_ok=True
            )

        # Copy vendor libraries to 'mysql/vendor' folder
        self.log.info("Copying vendor libraries")
        for src_folder, files in vendor_libs:
            self.log.info("Copying folder: %s", src_folder)
            for filepath in files:
                dst_folder, filename = os.path.split(filepath)
                src = Path(src_folder, filename)
                dst = Path(os.getcwd(), self.vendor_folder, dst_folder)
                if not Path(dst, src.name).exists():
                    self.log.debug("copying %s -> %s", src, dst)
                    shutil.copy2(src, dst, follow_symlinks=False)

        if os.name == "nt":
            self.distribution.package_data = {"mysql": ["vendor/plugin/*"]}
            site_packages_files = [
                os.path.join(openssl_libs_path, lib_n) for lib_n in openssl_libs
            ]
            site_packages_files.append(
                os.path.join(self.with_mysql_capi, "lib", "libmysql.dll")
            )

            # `SASL_WIN_LIBS` are loaded automatically as dependency of
            # authentication_ldap_sasl_client.dll. On Windows, they are expected to be
            # at `lib/site-packages` - next to `_mysql_connector`.
            sasl_dll_paths = [
                os.path.join(self.with_mysql_capi, "bin", dll) for dll in SASL_WIN_LIBS
            ]
            site_packages_files.extend(
                [path for path in sasl_dll_paths if os.path.exists(path)]
            )

            self.distribution.data_files = [
                ("lib\\site-packages\\", site_packages_files)
            ]

            # Also, we need to include the DLLs corresponding to the
            # SASL authorization methods.
            sasl_dll_auth_method_paths = [
                os.path.join(self.with_mysql_capi, "bin", "sasl2", dll)
                for dll in SASL_WIN_LIBS_AUTH_METHODS
                if os.path.exists(
                    os.path.join(self.with_mysql_capi, "bin", "sasl2", dll)
                )
            ]

            if sasl_dll_auth_method_paths:
                self.distribution.data_files.append(
                    ("lib\\site-packages\\sasl2", sasl_dll_auth_method_paths)
                )

            self.log.debug("# site_packages_files: %s", self.distribution.data_files)
        elif bundle_plugin_libs:
            # Bundle SASL libs
            sasl_libs_path = (
                Path(self.with_mysql_capi, "lib")
                if platform.system() == "Darwin"
                else Path(self.with_mysql_capi, "lib", "private")
            )
            if not os.path.exists(sasl_libs_path):
                self.log.info("sasl2 llibraries not found at %s", sasl_libs_path)
            sasl_libs = []
            sasl_plugin_libs_w = [
                "libsasl2.*.*",
                "libgssapi_krb5.*.*",
                "libgssapi_krb5.*.*",
                "libkrb5.*.*",
                "libk5crypto.*.*",
                "libkrb5support.*.*",
                "libcrypto.*.*.*",
                "libssl.*.*.*",
                "libcom_err.*.*",
                "libfido2.*.*",
            ]
            sasl_plugin_libs = []
            for sasl_lib in sasl_plugin_libs_w:
                lib_path_entries = glob(os.path.join(sasl_libs_path, sasl_lib))
                for lib_path_entry in lib_path_entries:
                    sasl_plugin_libs.append(os.path.basename(lib_path_entry))
            sasl_libs.append((sasl_libs_path, sasl_plugin_libs))

            # Copy vendor libraries to 'mysql/vendor/private' folder
            self.log.info("Copying vendor libraries")
            for src_folder, files in sasl_libs:
                self.log.info("Copying folder: %s", src_folder)
                for filename in files:
                    src = Path(src_folder, filename)
                    if not src.exists():
                        self.log.warn("Library not found: %s", src)
                        continue
                    dst = (
                        Path(os.getcwd(), self.vendor_folder)
                        if platform.system() == "Darwin"
                        else Path(os.getcwd(), self.vendor_folder, "private")
                    )
                    if not Path(dst, src.name).exists():
                        self.log.debug("copying %s -> %s", src, dst)
                        shutil.copy2(src, dst, follow_symlinks=False)

            # include sasl2 libs
            sasl2_libs = []
            sasl2_libs_path = os.path.join(
                self.with_mysql_capi, "lib", "private", "sasl2"
            )
            if not os.path.exists(sasl2_libs_path):
                self.log.info("sasl2 libraries not found at %s", sasl2_libs_path)
            sasl2_libs_w = [
                "libanonymous.*",
                "libcrammd5.*.*",
                "libdigestmd5.*.*.*.*",
                "libgssapiv2.*",
                "libplain.*.*",
                "libscram.*.*.*.*",
                "libanonymous.*.*",
                "libcrammd5.*.*.*.*",
                "libgs2.*",
                "libgssapiv2.*.*",
                "libplain.*.*.*.*",
                "libanonymous.*.*.*.*",
                "libdigestmd5.*",
                "libgs2.*.*",
                "libgssapiv2.*.*.*.*",
                "libscram.*",
                "libcrammd5.*",
                "libdigestmd5.*.*",
                "libgs2.*.*.*.*",
                "libplain.*",
                "libscram.*.*",
            ]

            sasl2_scram_libs = []
            for sasl2_lib in sasl2_libs_w:
                lib_path_entries = glob(os.path.join(sasl2_libs_path, sasl2_lib))
                for lib_path_entry in lib_path_entries:
                    sasl2_scram_libs.append(os.path.basename(lib_path_entry))

            sasl2_libs.append((sasl2_libs_path, sasl2_scram_libs))

            sasl2_libs_private_path = os.path.join(
                self.vendor_folder, "private", "sasl2"
            )
            if not os.path.exists(sasl2_libs_private_path):
                Path(sasl2_libs_private_path).mkdir(parents=True, exist_ok=True)

            # Copy vendor libraries to 'mysql/vendor/private/sasl2' folder
            self.log.info("Copying vendor libraries")
            dst = Path(os.getcwd(), sasl2_libs_private_path)
            for src_folder, files in sasl2_libs:
                self.log.info("Copying folder: %s", src_folder)
                for filename in files:
                    src = Path(src_folder, filename)
                    if not src.exists():
                        self.log.warning("Library not found: %s", src)
                        continue
                    if not Path(dst, filename).exists():
                        self.log.debug("copying %s -> %s", src, dst)
                        shutil.copy2(src, dst, follow_symlinks=False)

            # Copy libfido2 libraries to 'mysql/vendor/plugin' on macOS
            if platform.system() == "Darwin":
                dst = Path(os.getcwd(), self.vendor_folder, "plugin")
                libfido2_files = [
                    Path(filename).name
                    for filename in glob(
                        Path(self.vendor_folder, "libfido2.*.*").as_posix()
                    )
                ]
                for filename in libfido2_files:
                    src = Path(os.getcwd(), self.vendor_folder, filename)
                    if not Path(dst, filename).exists():
                        self.log.debug("copying %s -> %s", src, dst)
                        shutil.copy2(src, dst, follow_symlinks=False)

        self.distribution.package_data = {
            "mysql": [
                "vendor/*",
                "vendor/lib/*",
                "vendor/plugin/*",
                "vendor/private/*",
                "vendor/private/sasl2/*",
            ],
            "mysql.connector": ["py.typed"],
        }