# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem              1.0

name                    mysql8
version                 8.4.6

categories              databases

homepage                https://dev.mysql.com

maintainers             {gmail.com:herby.gillot @herbygillot} \
                        openmaintainer

# Set revision_client and revision_server to 0 on version bump.
set revision_client     1
set revision_server     0

set name_mysql          ${name}
set version_branch      [join [lrange [split ${version} .] 0 1] .]

# Undefined symbols for architecture x86_64:
#   "std::bad_optional_access::~bad_optional_access()", referenced from:
platform darwin {
    if {${os.major} < 17} {
        known_fail yes
        pre-fetch {
            ui_error "${name} @${version} requires macOS 10.13 or newer."
            return -code error "incompatible macOS version"
        }
    }
}

if {$subport eq $name} {
    PortGroup           muniversal                  1.0
    PortGroup           cmake                       1.1
    PortGroup           select                      1.0
    PortGroup           openssl                     1.0

    description         Multithreaded SQL database server
    long_description    MySQL is an open-source, multi-threaded SQL database.
    # https://downloads.mysql.com/docs/licenses/mysqld-8.0-gpl-en.pdf
    license             {GPL-2 OpenSSLException}

    revision            ${revision_client}

    master_sites        mysql:MySQL-${version_branch}:mysql

    distname            mysql-${version}

    distfiles           ${distname}${extract.suffix}:mysql

    checksums           ${distname}${extract.suffix} \
                        rmd160  70f98b3fa56fb3b8c7293497ac064fe0a643837c \
                        sha256  a1e523dc8be96d18a5ade106998661285ca01b6f5b46c08b2654110e40df2fb7 \
                        size    479211975

    depends_build-append \
                        port:pkgconfig  \
                        port:bison

    depends_lib-append  path:lib/pkgconfig/icu-uc.pc:icu \
                        port:curl           \
                        port:cyrus-sasl2    \
                        port:libedit        \
                        port:libfido2       \
                        port:libevent       \
                        path:lib/libldap.dylib:openldap       \
                        port:protobuf3-cpp  \
                        port:zlib           \
                        port:zstd

    depends_run-append  port:mysql_select

    select.group        mysql
    select.file         ${filespath}/${name_mysql}

    use_parallel_build  yes

    # llvm on Ventura (macOS 13) has issues throwing the folllwing error:
    # Undefined symbols "std::exception_ptr::__from_native_exception_pointer(void*)", "___cxa_init_primary_exception"
    # Use macports llvm until this is fixed upstream
    # See https://trac.macports.org/ticket/70323
    # macports-clang-16 was the only clang that successfully built mysql on Ventura (17 and 18 hung)
    if {${os.major} == 22} {
        configure.compiler macports-clang-16
    }

    compiler.cxx_standard 2020

    # /usr/include/c++/v1/optional:960:34: note: candidate function not viable: no known conversion from 'optional<...>' to 'const optional<...>' for object argument
    compiler.blacklist-append {clang < 1100}

    # Use default CMake build_types
    if {[variant_isset debug]} {
        cmake.build_type    Debug

        configure.args-append \
            -DWITH_DEBUG:BOOL=ON \
            -DINSTALL_MYSQLTESTDIR:PATH="share/${name_mysql}/mysql-test" \
            -DWITH_UNIT_TESTS=ON
    } else {
        cmake.build_type    Release

        configure.args-append \
            -DWITH_DEBUG=OFF \
            -DWITH_UNIT_TESTS=OFF
    }

    # Disable RPATH
    cmake.install_rpath {}
    configure.args-delete \
        -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON \
        -DCMAKE_INSTALL_RPATH="[join [option cmake.install_rpath] \;]"
    configure.pre_args-delete \
        -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON \
        -DCMAKE_INSTALL_RPATH="[join [option cmake.install_rpath] \;]"
    configure.args-append \
        -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=OFF

    configure.args-delete \
        -DCMAKE_INSTALL_NAME_DIR="${cmake.install_prefix}/lib"
    configure.args-append \
        -DCMAKE_INSTALL_NAME_DIR:PATH="${prefix}/lib/${name_mysql}/mysql"

    # Build configuration
    configure.args-append \
        -DBISON_EXECUTABLE="${prefix}/bin/bison" \
        -DFORCE_UNSUPPORTED_COMPILER=ON \
        -DINSTALL_LAYOUT:STRING=MACPORTS \
        -DMYSQL_DATADIR:PATH="${prefix}/var/db/${name_mysql}" \
        -DMYSQL_UNIX_ADDR:PATH="${prefix}/var/run/${name_mysql}/mysqld.sock" \
        -DSYSCONFDIR:PATH="${prefix}/etc/${name_mysql}" \
        -DWITH_UNIT_TESTS=OFF   \
        -DWITH_CURL=system      \
        -DWITH_EDITLINE=system  \
        -DWITH_FIDO=system      \
        -DWITH_ICU=system       \
        -DWITH_LDAP=system      \
        -DWITH_LZ4=system       \
        -DWITH_PROTOBUF=system  \
        -DWITH_SASL=system      \
        -DWITH_ZLIB=system      \
        -DWITH_ZSTD=system


    # Per the mysql8 devs, setting -DCMAKE_PREFIX_PATH the {macports_prefx}/lib file
    # forces the cmake build process to use the macports "system"
    configure.args-append \
        -DCMAKE_PREFIX_PATH=${prefix}/lib

    # per the mysql8 devs, if -DWITH_SSL is set to "system" no attempts are made to copy and
    # update the openssl / libcrypto libs into the mysql directory using the macports
    # files in place.  Since we'll be using the macports libs in place, the mysql8 devs also
    # suggest setting -DCMAKE_PREFIX_PATH to aide cmake in finding the preferred version of openssl
    configure.args-append \
        -DCMAKE_PREFIX_PATH=[openssl::install_area] \
        -DWITH_SSL=system

    configure.args-append \
        -DWITH_ROUTER:BOOL=OFF

    patch.pre_args-replace  -p0 -p1
    patchfiles      patch-cmake-install_layout.cmake.diff \
                    patch-readline.cmake.diff \
                    patch-scripts-cmakelists.diff \
                    patch-no_warn_duplicate_libraries.diff

    post-extract {
        file mkdir ${cmake.build_dir}/macports
        copy ${filespath}/macports-default.cnf \
            ${filespath}/my.cnf \
            ${cmake.build_dir}/macports/
    }

    pre-configure {
        # removing these three ssl related configure flags added by the openssl portgroup is required
        # to use the macports openssl / libcrypto libs in place. per the mysql8 devs, this is the
        # preferred method to the copy and update method
        configure.args-delete \
            -DOPENSSL_INCLUDE_DIR=[openssl::include_dir] \
            -DWITH_SSL=[openssl::install_area]
    }

    post-patch {

        reinplace "s|@NAME@|${name_mysql}|g" \
            ${worksrcpath}/cmake/install_layout.cmake
        reinplace "s|@NAME@|${name_mysql}|g" \
            ${cmake.build_dir}/macports/macports-default.cnf \
            ${cmake.build_dir}/macports/my.cnf
        reinplace "s|@PREFIX@|${prefix}|g" \
            ${cmake.build_dir}/macports/macports-default.cnf \
            ${cmake.build_dir}/macports/my.cnf \
            ${worksrcpath}/cmake/readline.cmake
    }

    post-destroot {
        # Remove tests
        file delete -force -- ${destroot}${prefix}/share/${name_mysql}/mysql-test

        # proc portdestroot::destroot_finish fails to find and compress our man pages
        # so borrow the compress command and run on our files now.
        set manpath "${destroot}${prefix}/share/man"
        set gzip [findBinary gzip ${portutil::autoconf::gzip_path}]

        foreach manpage [glob -type f ${destroot}${prefix}/share/man/${name_mysql}/man\[1-9\]/*] {
            # Fix paths in manpages
            reinplace -q "s|/etc/|${prefix}/etc/${name_mysql}/|g" ${manpage}
            # Compress all manpages with gzip
            system "$gzip -9vf ${manpage}"
        }

        xinstall -m 0755 -o root -d ${destroot}${prefix}/etc/${name_mysql}

        copy ${cmake.build_dir}/macports/macports-default.cnf \
            ${destroot}${prefix}/etc/${name_mysql}/

        xinstall -m 0755 -o root -d \
            ${destroot}${prefix}/share/${name_mysql}/support-files/macports

        copy ${cmake.build_dir}/macports/my.cnf \
            ${destroot}${prefix}/share/${name_mysql}/support-files/macports/

        # Work around bad zlib linker flags in `mysql_config`.
        # https://bugs.mysql.com/bug.php?id=111011
        # https://trac.macports.org/ticket/68002
        reinplace -q "s|-lzlib|-lz|g" ${destroot}${prefix}/lib/${name_mysql}/bin/mysql_config
    }

    post-install {
        if {![file exists ${prefix}/etc/LaunchDaemons/org.macports.${name_mysql}/org.macports.${name_mysql}-server.plist]} {
            ui_msg "The ${name_mysql} client has been installed."
            ui_msg "To install the ${name_mysql} server, install the ${name_mysql}-server port."
        }
    }

    post-activate {
        if {![file exists ${prefix}/etc/${name_mysql}/my.cnf]} {
            copy ${prefix}/share/${name_mysql}/support-files/macports/my.cnf \
                ${prefix}/etc/${name_mysql}/
        }
    }

    notes "
On activation if no ${prefix}/etc/${name_mysql}/my.cnf file exists one
will be created which loads
${prefix}/etc/${name_mysql}/macports-default.cnf.

If a ${prefix}/etc/${name_mysql}/my.cnf file exists MacPorts does not
touch it and any changes you make to ${prefix}/etc/${name_mysql}/my.cnf
will be preserved (e.g., during port upgrades, deactivations or
activations). ${prefix}/etc/${name_mysql}/my.cnf is a good place to
customize your ${name_mysql} installation.

Any changes made to ${prefix}/etc/${name_mysql}/macports-default.cnf
will be lost during port upgrades, deactivations or activations so you
are advised to not make changes here. Currently
${prefix}/etc/${name_mysql}/macports-default.cnf contains only one
directive; to disable networking. With disabled networking it is
possible to install and have running all the MacPorts mysql ports
simultaneously.

To set ${name_mysql} as your preferred version of MySQL, use `port select`,
as follows:

\$ sudo port select mysql ${name_mysql}
"

    livecheck.type      regex
    livecheck.url       https://dev.mysql.com/downloads/mysql/${version_branch}.html
    livecheck.regex     "MySQL Community Server (${version_branch}(\.\[0-9.\]+)?)"
}

subport ${name_mysql}-server {
    revision            ${revision_server}
    license             BSD
    description         Run ${name_mysql} as server
    long_description    {*}${description}

    supported_archs     noarch
    distfiles

    depends_run         port:${name_mysql}

    if {"darwin" eq ${os.platform} && ${os.major} > 8} {
        set mysqluser       _mysql
    } else {
        set mysqluser       mysql
    }
    add_users ${mysqluser} group=${mysqluser} realname=MySQL\ Server

    set log_file ${prefix}/var/log/${name}/mysql.log

    pre-extract {
        copy ${filespath}/org.macports.mysql-server.plist \
             ${workpath}/org.macports.${subport}.plist
    }

    post-patch {
        reinplace "s|@NAMEMYSQL@|${name_mysql}|g" \
            ${workpath}/org.macports.${subport}.plist
        reinplace "s|@PREFIX@|${prefix}|g" \
            ${workpath}/org.macports.${subport}.plist
        reinplace "s|@SUBPORT@|${subport}|g" \
            ${workpath}/org.macports.${subport}.plist
        reinplace "s|@USER@|${mysqluser}|g" \
            ${workpath}/org.macports.${subport}.plist
        reinplace "s|@GROUP@|${mysqluser}|g" \
            ${workpath}/org.macports.${subport}.plist
        reinplace "s|@LOGFILE@|${log_file}|g" \
            ${workpath}/org.macports.${subport}.plist
    }

    use_configure       no

    build {}

    destroot {
        xinstall -d -m 0755 -o ${mysqluser} -g ${mysqluser} \
            [file dirname ${destroot}${log_file}]

        touch ${destroot}${log_file}
        file attributes ${destroot}${log_file} -o ${mysqluser} -g ${mysqluser}

        xinstall -d -m 0755 ${destroot}${prefix}/etc/LaunchDaemons/org.macports.${subport}

        xinstall -m 0644 -o root -W ${workpath} \
            org.macports.${subport}.plist \
            ${destroot}${prefix}/etc/LaunchDaemons/org.macports.${subport}

        xinstall -d -m 0755 ${destroot}/Library/LaunchDaemons

        ln -s ${prefix}/etc/LaunchDaemons/org.macports.${subport}/org.macports.${subport}.plist \
            ${destroot}/Library/LaunchDaemons/org.macports.${subport}.plist

        xinstall -m 0755 -o root -d \
            ${destroot}${prefix}/var/run

        xinstall -m 0755 -o ${mysqluser} -g ${mysqluser} -d \
            ${destroot}${prefix}/etc/${name_mysql} \
            ${destroot}${prefix}/var/db/${name_mysql} \
            ${destroot}${prefix}/var/log/${name_mysql} \
            ${destroot}${prefix}/var/run/${name_mysql}

        xinstall -m 0700 -o ${mysqluser} -g ${mysqluser} -d \
            ${destroot}${prefix}/var/db/${name_mysql}-files \
            ${destroot}${prefix}/var/db/${name_mysql}-keyring

        destroot.keepdirs-append  \
            ${destroot}${prefix}/var/db/${name_mysql} \
            ${destroot}${prefix}/var/db/${name_mysql}-files \
            ${destroot}${prefix}/var/db/${name_mysql}-keyring \
            ${destroot}${prefix}/var/log/${name_mysql} \
            ${destroot}${prefix}/var/run/${name_mysql}
    }

    notes "
If this is a new install you might want to run:

\$ sudo ${prefix}/lib/${name_mysql}/bin/mysqld --initialize --user=${mysqluser}
\$ sudo port load ${name_mysql}-server
\$ ${prefix}/lib/${name_mysql}/bin/mysql_secure_installation

The first command creates the necessary files for the MySQL database service.
(Remember to make a note of the auto-generated root password from this step.)
The second command starts the MySQL service.
The last command helps to improve the security of your running MySQL instance.

Once enabled, the MySQL logs can be found in:
[file dirname $log_file]
"

    livecheck.type          none
}
