#!/usr/bin/env python
# Copyright 1998-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

try:
    from setuptools.core import setup, Command, Extension
    from setuptools.command.build import build
    from setuptools.command.build_ext import build_ext as _build_ext
    from setuptools.command.build_scripts import build_scripts
    from setuptools.command.clean import clean
    from setuptools.command.install import install
    from setuptools.command.install_data import install_data
    from setuptools.command.install_lib import install_lib
    from setuptools.command.install_scripts import install_scripts
    from setuptools.command.sdist import sdist
    from setuptools.dep_util import newer
    from setuptools.dir_util import mkpath, remove_tree
    from setuptools.util import change_root, subst_vars
except ImportError:
    from distutils.core import setup, Command, Extension
    from distutils.command.build import build
    from distutils.command.build_ext import build_ext as _build_ext
    from distutils.command.build_scripts import build_scripts
    from distutils.command.clean import clean
    from distutils.command.install import install
    from distutils.command.install_data import install_data
    from distutils.command.install_lib import install_lib
    from distutils.command.install_scripts import install_scripts
    from distutils.command.sdist import sdist
    from distutils.dep_util import newer
    from distutils.dir_util import mkpath, remove_tree
    from distutils.util import change_root, subst_vars

import codecs
import collections
import glob
import itertools
import os
import os.path
import platform
import re
import subprocess
import sys

autodetect_pip = os.path.basename(os.environ.get("_", "")) == "pip" or os.path.basename(
    os.path.dirname(__file__)
).startswith("pip-")
venv_prefix = "" if sys.prefix == sys.base_prefix else sys.prefix
create_entry_points = bool(autodetect_pip or venv_prefix)
with open(os.path.join(os.path.dirname(__file__), "README.md"), "rt") as f:
    long_description = f.read()

# TODO:
# - smarter rebuilds of docs w/ 'install_docbook' and 'install_apidoc'.

# Dictionary of scripts.  The structure is
#   key   = location in filesystem to install the scripts
#   value = list of scripts, path relative to top source directory
x_scripts = {
    "bin": [
        "bin/ebuild",
        "bin/egencache",
        "bin/emerge",
        "bin/emerge-webrsync",
        "bin/emirrordist",
        "bin/glsa-check",
        "bin/portageq",
        "bin/quickpkg",
    ],
    "sbin": [
        "bin/archive-conf",
        "bin/dispatch-conf",
        "bin/emaint",
        "bin/env-update",
        "bin/etc-update",
        "bin/fixpackages",
        "bin/regenworld",
    ],
}

# Dictionary custom modules written in C/C++ here.  The structure is
#   key   = module name
#   value = list of C/C++ source code, path relative to top source directory
x_c_helpers = {
    "portage.util.libc": [
        "src/portage_util_libc.c",
    ],
}

if platform.system() == "Linux":
    x_c_helpers.update(
        {
            "portage.util.file_copy.reflink_linux": [
                "src/portage_util_file_copy_reflink_linux.c",
            ],
        }
    )


class x_build(build):
    """Build command with extra build_man call."""

    def run(self):
        build.run(self)
        self.run_command("build_man")


class build_man(Command):
    """Perform substitutions in manpages."""

    user_options = []

    def initialize_options(self):
        self.build_base = None

    def finalize_options(self):
        self.set_undefined_options("build", ("build_base", "build_base"))

    def run(self):
        for d, files in self.distribution.data_files:
            if not d.startswith("$mandir/"):
                continue

            for source in files:
                target = os.path.join(self.build_base, source)
                mkpath(os.path.dirname(target))

                if not newer(source, target) and not newer(__file__, target):
                    continue

                print("copying and updating %s -> %s" % (source, target))

                with codecs.open(source, "r", "utf8") as f:
                    data = f.readlines()
                data[0] = data[0].replace("VERSION", self.distribution.get_version())
                with codecs.open(target, "w", "utf8") as f:
                    f.writelines(data)


class docbook(Command):
    """Build docs using docbook."""

    user_options = [
        (
            "doc-formats=",
            None,
            "Documentation formats to build (all xmlto formats for docbook are allowed, comma-separated",
        ),
    ]

    def initialize_options(self):
        self.doc_formats = "xhtml,xhtml-nochunks"

    def finalize_options(self):
        self.doc_formats = self.doc_formats.replace(",", " ").split()

    def run(self):
        if not os.path.isdir("doc/fragment"):
            mkpath("doc/fragment")

        with open("doc/fragment/date", "w"):
            pass
        with open("doc/fragment/version", "w") as f:
            f.write("<releaseinfo>%s</releaseinfo>" % self.distribution.get_version())

        for f in self.doc_formats:
            print("Building docs in %s format..." % f)
            subprocess.check_call(
                ["xmlto", "-o", "doc", "-m", "doc/custom.xsl", f, "doc/portage.docbook"]
            )


class apidoc(Command):
    """Build API docs using apidoc."""

    user_options = []

    def initialize_options(self):
        self.build_lib = None

    def finalize_options(self):
        self.set_undefined_options("build_py", ("build_lib", "build_lib"))

    def run(self):
        self.run_command("build_py")

        print("Building API documentation...")

        process_env = os.environ.copy()
        pythonpath = self.build_lib
        try:
            pythonpath += ":" + process_env["PYTHONPATH"]
        except KeyError:
            pass
        process_env["PYTHONPATH"] = pythonpath

        subprocess.check_call(["make", "-C", "doc/api", "html"], env=process_env)


class install_docbook(install_data):
    """install_data for docbook docs"""

    user_options = install_data.user_options + [
        ("htmldir=", None, "HTML documentation install directory"),
    ]

    def initialize_options(self):
        install_data.initialize_options(self)
        self.htmldir = None

    def finalize_options(self):
        self.set_undefined_options("install", ("htmldir", "htmldir"))
        install_data.finalize_options(self)

    def run(self):
        if not os.path.exists("doc/portage.html"):
            self.run_command("docbook")
        self.data_files = [
            (self.htmldir, glob.glob("doc/*.html")),
        ]
        install_data.run(self)


class install_apidoc(install_data):
    """install_data for apidoc docs"""

    user_options = install_data.user_options + [
        ("htmldir=", None, "HTML documentation install directory"),
    ]

    def initialize_options(self):
        install_data.initialize_options(self)
        self.htmldir = None

    def finalize_options(self):
        self.set_undefined_options("install", ("htmldir", "htmldir"))
        install_data.finalize_options(self)

    def run(self):
        if not os.path.exists("doc/api/build/html/index.html"):
            self.run_command("apidoc")
        self.data_files = [
            (
                os.path.join(self.htmldir, "api"),
                glob.glob("doc/api/build/html/*.html")
                + glob.glob("doc/api/build/html/*.js"),
            ),
            (
                os.path.join(self.htmldir, "api/_static"),
                glob.glob("doc/api/build/html/_static/*"),
            ),
        ]
        install_data.run(self)


class x_build_scripts_custom(build_scripts):
    def finalize_options(self):
        build_scripts.finalize_options(self)
        if "dir_name" in dir(self):
            self.build_dir = os.path.join(self.build_dir, self.dir_name)
            if self.dir_name in x_scripts:
                self.scripts = x_scripts[self.dir_name]
            else:
                self.scripts = set(self.scripts)
                if not (create_entry_points and self.dir_name == "portage"):
                    for other_files in x_scripts.values():
                        self.scripts.difference_update(other_files)

    def run(self):
        # group scripts by subdirectory
        split_scripts = collections.defaultdict(list)
        for f in self.scripts:
            dir_name = os.path.dirname(f[len("bin/") :])
            split_scripts[dir_name].append(f)

        base_dir = self.build_dir
        base_scripts = self.scripts
        for d, files in split_scripts.items():
            self.build_dir = os.path.join(base_dir, d)
            self.scripts = files
            self.copy_scripts()

        # restore previous values
        self.build_dir = base_dir
        self.scripts = base_scripts


class x_build_scripts_bin(x_build_scripts_custom):
    dir_name = "bin"


class x_build_scripts_sbin(x_build_scripts_custom):
    dir_name = "sbin"


class x_build_scripts_portagebin(x_build_scripts_custom):
    dir_name = "portage"


class x_build_scripts(build_scripts):
    def initialize_option(self):
        build_scripts.initialize_options(self)

    def finalize_options(self):
        build_scripts.finalize_options(self)

    def run(self):
        self.run_command("build_scripts_bin")
        self.run_command("build_scripts_portagebin")
        self.run_command("build_scripts_sbin")


class x_clean(clean):
    """clean extended for doc & post-test cleaning"""

    @staticmethod
    def clean_docs():
        def get_doc_outfiles():
            for dirpath, _dirnames, filenames in os.walk("doc"):
                for f in filenames:
                    if f.endswith(".docbook") or f == "custom.xsl":
                        pass
                    else:
                        yield os.path.join(dirpath, f)

                # do not recurse
                break

        for f in get_doc_outfiles():
            print("removing %s" % repr(f))
            os.remove(f)

        if os.path.isdir("doc/fragment"):
            remove_tree("doc/fragment")

        if os.path.isdir("doc/api/build"):
            remove_tree("doc/api/build")

    def clean_tests(self):
        # do not remove incorrect dirs accidentally
        top_dir = os.path.normpath(os.path.join(self.build_lib, ".."))
        cprefix = os.path.commonprefix((self.build_base, top_dir))
        if cprefix != self.build_base:
            return

        bin_dir = os.path.join(top_dir, "bin")
        if os.path.exists(bin_dir):
            remove_tree(bin_dir)

        conf_dir = os.path.join(top_dir, "cnf")
        if os.path.islink(conf_dir):
            print("removing %s symlink" % repr(conf_dir))
            os.unlink(conf_dir)

        pni_file = os.path.join(top_dir, ".portage_not_installed")
        if os.path.exists(pni_file):
            print("removing %s" % repr(pni_file))
            os.unlink(pni_file)

    def clean_man(self):
        man_dir = os.path.join(self.build_base, "man")
        if os.path.exists(man_dir):
            remove_tree(man_dir)

    def run(self):
        if self.all:
            self.clean_tests()
            self.clean_docs()
            self.clean_man()

        clean.run(self)


class x_install(install):
    """install command with extra Portage paths"""

    user_options = install.user_options + [
        # note: $prefix and $exec_prefix are reserved for Python install
        ("system-prefix=", None, "Prefix for architecture-independent data"),
        ("system-exec-prefix=", None, "Prefix for architecture-specific data"),
        ("bindir=", None, "Install directory for main executables"),
        ("datarootdir=", None, "Data install root directory"),
        ("docdir=", None, "Documentation install directory"),
        ("htmldir=", None, "HTML documentation install directory"),
        ("mandir=", None, "Manpage root install directory"),
        ("portage-base=", "b", "Portage install base"),
        (
            "portage-bindir=",
            None,
            "Install directory for Portage internal-use executables",
        ),
        ("portage-datadir=", None, "Install directory for data files"),
        ("sbindir=", None, "Install directory for superuser-intended executables"),
        ("sysconfdir=", None, "System configuration path"),
    ]

    # note: the order is important for proper substitution
    paths = [
        ("system_prefix", "/usr"),
        ("system_exec_prefix", "$system_prefix"),
        ("bindir", "$system_exec_prefix/bin"),
        ("sbindir", "$system_exec_prefix/sbin"),
        ("sysconfdir", "/etc"),
        ("datarootdir", "$system_prefix/share"),
        ("docdir", "$datarootdir/doc/$package-$version"),
        ("htmldir", "$docdir/html"),
        ("mandir", "$datarootdir/man"),
        ("portage_base", "$system_exec_prefix/lib/portage"),
        ("portage_bindir", "$portage_base/bin"),
        ("portage_datadir", "$datarootdir/portage"),
        # not customized at the moment
        ("logrotatedir", "$sysconfdir/logrotate.d"),
        ("portage_confdir", "$portage_datadir/config"),
        ("portage_setsdir", "$portage_confdir/sets"),
    ]

    def initialize_options(self):
        install.initialize_options(self)

        for key, default in self.paths:
            setattr(self, key, default)
        self.subst_paths = {}

    def finalize_options(self):
        install.finalize_options(self)

        # substitute variables
        new_paths = {
            "package": self.distribution.get_name(),
            "version": self.distribution.get_version(),
        }
        for key, _default in self.paths:
            new_paths[key] = subst_vars(getattr(self, key), new_paths)
            setattr(self, key, new_paths[key])
        self.subst_paths = new_paths


class x_install_data(install_data):
    """install_data with customized path support"""

    user_options = install_data.user_options

    def initialize_options(self):
        install_data.initialize_options(self)
        self.build_base = None
        self.paths = None

    def finalize_options(self):
        install_data.finalize_options(self)
        self.set_undefined_options("build", ("build_base", "build_base"))
        self.set_undefined_options("install", ("subst_paths", "paths"))

    def run(self):
        def re_sub_file(path, pattern, repl):
            print("Rewriting %s" % path)
            with codecs.open(path, "r", "utf-8") as f:
                data = f.read()
            data = re.sub(pattern, repl, data, flags=re.MULTILINE)
            with codecs.open(path, "w", "utf-8") as f:
                f.write(data)

        if create_entry_points:
            re_sub_file("cnf/repos.conf", r"= /", "= %(EPREFIX)s/")
            re_sub_file("cnf/make.globals", r'DIR="/', 'DIR="${EPREFIX}/')

        self.run_command("build_man")

        def process_data_files(df):
            for d, files in df:
                # substitute man sources
                if d.startswith("$mandir/"):
                    files = [os.path.join(self.build_base, v) for v in files]

                # substitute variables in path
                d = subst_vars(d, self.paths)
                yield (d, files)

        old_data_files = self.data_files
        self.data_files = process_data_files(self.data_files)

        install_data.run(self)
        self.data_files = old_data_files


class x_install_lib(install_lib):
    """install_lib command with Portage path substitution"""

    user_options = install_lib.user_options

    def initialize_options(self):
        install_lib.initialize_options(self)
        self.portage_base = None
        self.portage_bindir = None
        self.portage_confdir = None

    def finalize_options(self):
        install_lib.finalize_options(self)
        self.set_undefined_options(
            "install",
            ("portage_base", "portage_base"),
            ("portage_bindir", "portage_bindir"),
            ("portage_confdir", "portage_confdir"),
        )

    def install(self):
        ret = install_lib.install(self)

        def rewrite_file(path, val_dict):
            path = os.path.join(self.install_dir, path)
            print("Rewriting %s" % path)
            with codecs.open(path, "r", "utf-8") as f:
                data = f.read()

            for varname, val in val_dict.items():
                regexp = r"(?m)^(%s\s*=).*$" % varname
                repl = r"\1 %s" % repr(val)

                data = re.sub(regexp, repl, data)

            with codecs.open(path, "w", "utf-8") as f:
                f.write(data)

        rewrite_file(
            "portage/__init__.py",
            {
                "VERSION": self.distribution.get_version(),
            },
        )

        def re_sub_file(path, pattern_repl_items):
            path = os.path.join(self.install_dir, path)
            print("Rewriting %s" % path)
            with codecs.open(path, "r", "utf-8") as f:
                data = f.read()
            for pattern, repl in pattern_repl_items:
                data = re.sub(pattern, repl, data, flags=re.MULTILINE)
            with codecs.open(path, "w", "utf-8") as f:
                f.write(data)

        val_dict = {}
        if create_entry_points:
            re_sub_file(
                "portage/const.py",
                (
                    (
                        r"^(GLOBAL_CONFIG_PATH\s*=\s*[\"'])(.*)([\"'])",
                        lambda m: "{}{}{}".format(
                            m.group(1),
                            m.group(2).partition("/usr")[-1],
                            m.group(3),
                        ),
                    ),
                    (
                        r"^(PORTAGE_BASE_PATH\s*=\s*)(.*)",
                        lambda m: "{}{}".format(
                            m.group(1),
                            'os.path.join(os.path.realpath(__import__("sys").prefix), "lib/portage")',
                        ),
                    ),
                    (
                        r"^(EPREFIX\s*=\s*)(.*)",
                        lambda m: "{}{}".format(
                            m.group(1),
                            '__import__("sys").prefix',
                        ),
                    ),
                ),
            )
        else:
            val_dict.update(
                {
                    "PORTAGE_BASE_PATH": self.portage_base,
                    "PORTAGE_BIN_PATH": self.portage_bindir,
                }
            )
        rewrite_file("portage/const.py", val_dict)

        return ret


class x_install_scripts_custom(install_scripts):
    def initialize_options(self):
        install_scripts.initialize_options(self)
        self.root = None

    def finalize_options(self):
        self.set_undefined_options(
            "install", ("root", "root"), (self.var_name, "install_dir")
        )
        install_scripts.finalize_options(self)
        self.build_dir = os.path.join(self.build_dir, self.dir_name)

        # prepend root
        if self.root is not None:
            self.install_dir = change_root(self.root, self.install_dir)

    def run(self):
        if not create_entry_points:
            install_scripts.run(self)


class x_install_scripts_bin(x_install_scripts_custom):
    dir_name = "bin"
    var_name = "bindir"


class x_install_scripts_sbin(x_install_scripts_custom):
    dir_name = "sbin"
    var_name = "sbindir"


class x_install_scripts_portagebin(x_install_scripts_custom):
    dir_name = "portage"
    var_name = "portage_bindir"


class x_install_scripts(install_scripts):
    def initialize_option(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        self.run_command("install_scripts_bin")
        self.run_command("install_scripts_portagebin")
        self.run_command("install_scripts_sbin")


class x_sdist(sdist):
    """sdist defaulting to .tar.bz2 format, and archive files owned by root"""

    def finalize_options(self):
        if self.owner is None:
            self.owner = "root"
        if self.group is None:
            self.group = "root"

        sdist.finalize_options(self)


class build_tests(x_build_scripts_custom):
    """Prepare build dir for running tests."""

    def initialize_options(self):
        x_build_scripts_custom.initialize_options(self)
        self.build_base = None
        self.build_lib = None

    def finalize_options(self):
        x_build_scripts_custom.finalize_options(self)
        self.set_undefined_options(
            "build", ("build_base", "build_base"), ("build_lib", "build_lib")
        )

        # since we will be writing to $build_lib/.., it is important
        # that we do not leave $build_base
        self.top_dir = os.path.normpath(os.path.join(self.build_lib, ".."))
        cprefix = os.path.commonprefix((self.build_base, self.top_dir))
        if cprefix != self.build_base:
            raise SystemError("build_lib must be a subdirectory of build_base")

        self.build_dir = os.path.join(self.top_dir, "bin")

    def run(self):
        self.run_command("build_py")

        # install all scripts $build_lib/../bin
        # (we can't do a symlink since we want shebangs corrected)
        x_build_scripts_custom.run(self)

        # symlink 'cnf' directory
        conf_dir = os.path.join(self.top_dir, "cnf")
        if os.path.exists(conf_dir):
            if not os.path.islink(conf_dir):
                raise SystemError(
                    "%s exists and is not a symlink (collision)" % repr(conf_dir)
                )
            os.unlink(conf_dir)
        conf_src = os.path.relpath("cnf", self.top_dir)
        print("Symlinking %s -> %s" % (conf_dir, conf_src))
        os.symlink(conf_src, conf_dir)

        # create $build_lib/../.portage_not_installed
        # to enable proper paths in tests
        with open(os.path.join(self.top_dir, ".portage_not_installed"), "w"):
            pass


class test(Command):
    """run tests"""

    user_options = []

    def initialize_options(self):
        self.build_lib = None

    def finalize_options(self):
        self.set_undefined_options("build", ("build_lib", "build_lib"))

    def run(self):
        self.run_command("build_tests")
        subprocess.check_call(
            [
                sys.executable,
                "-bWd",
                os.path.join(self.build_lib, "portage/tests/runTests.py"),
            ]
        )


def find_packages():
    for dirpath, _dirnames, filenames in os.walk("lib"):
        if "__init__.py" in filenames:
            yield os.path.relpath(dirpath, "lib")


def find_scripts():
    for dirpath, _dirnames, filenames in os.walk("bin"):
        for f in filenames:
            if f not in ["deprecated-path"]:
                yield os.path.join(dirpath, f)


def get_manpages():
    linguas = os.environ.get("LINGUAS")
    if linguas is not None:
        linguas = linguas.split()

    for dirpath, _dirnames, filenames in os.walk("man"):
        groups = collections.defaultdict(list)
        for f in filenames:
            _fn, suffix = f.rsplit(".", 1)
            groups[suffix].append(os.path.join(dirpath, f))

        topdir = dirpath[len("man/") :]
        if not topdir or linguas is None or topdir in linguas:
            for g, mans in groups.items():
                yield [os.path.join("$mandir", topdir, "man%s" % g), mans]


class build_ext(_build_ext):
    user_options = _build_ext.user_options + [
        (
            "portage-ext-modules",
            None,
            "enable portage's C/C++ extensions (cross-compiling is not supported)",
        ),
    ]

    boolean_options = _build_ext.boolean_options + [
        "portage_ext_modules",
    ]

    def initialize_options(self):
        _build_ext.initialize_options(self)
        self.portage_ext_modules = None

    def run(self):
        if self.portage_ext_modules:
            _build_ext.run(self)


def venv_data_files(locations):
    if not create_entry_points:
        return
    for dest_prefix, source_path, file_args in locations:
        specific_files = []
        mode_arg = None
        for arg in file_args:
            if arg.startswith("-m"):
                mode_arg = int(arg[2:], 8)
            else:
                specific_files.append(arg)

        abs_source_path = os.path.abspath(source_path)
        for root, dirs, files in os.walk(abs_source_path):

            root_offset = root[len(abs_source_path) :].lstrip("/")
            dest_path = os.path.join(dest_prefix, root_offset)

            if specific_files:
                matched_files = list(
                    itertools.chain.from_iterable(
                        glob.glob(os.path.join(root, x)) for x in specific_files
                    )
                )
            else:
                matched_files = [os.path.join(root, x) for x in files]

            if mode_arg:
                for filename in matched_files:
                    if not os.path.islink(filename):
                        os.chmod(filename, mode_arg)

            yield (dest_path, matched_files)


def get_data_files(regular_files, venv_files):
    if create_entry_points:
        return list(venv_data_files(venv_files))

    return regular_files


setup(
    name="portage",
    version="3.0.28",
    url="https://wiki.gentoo.org/wiki/Project:Portage",
    project_urls={
        "Release Notes": "https://gitweb.gentoo.org/proj/portage.git/plain/RELEASE-NOTES",
        "Documentation": "https://wiki.gentoo.org/wiki/Handbook:AMD64/Working/Portage",
    },
    author="Gentoo Portage Development Team",
    author_email="dev-portage@gentoo.org",
    description="Portage is the package management and distribution system for Gentoo",
    license="GPLV2",
    long_description=long_description,
    long_description_content_type="text/markdown",
    package_dir={"": "lib"},
    packages=list(find_packages()),
    # something to cheat build & install commands
    scripts=list(find_scripts()),
    data_files=get_data_files(
        list(get_manpages())
        + [
            ["$sysconfdir", ["cnf/etc-update.conf", "cnf/dispatch-conf.conf"]],
            ["$logrotatedir", ["cnf/logrotate.d/elog-save-summary"]],
            [
                "$portage_confdir",
                ["cnf/make.conf.example", "cnf/make.globals", "cnf/repos.conf"],
            ],
            ["$portage_setsdir", ["cnf/sets/portage.conf"]],
            ["$docdir", ["NEWS", "RELEASE-NOTES"]],
            ["$portage_base/bin", ["bin/deprecated-path"]],
            ["$sysconfdir/portage/repo.postsync.d", ["cnf/repo.postsync.d/example"]],
        ],
        [
            ("etc", "cnf", ("etc-update.conf", "dispatch-conf.conf")),
            ("etc/logrotate.d", "cnf/logrotate.d", ("elog-save-summary",)),
            ("etc/portage/repo.postsync.d", "cnf/repo.postsync.d", ("example",)),
            (
                "share/portage/config",
                "cnf",
                ("make.conf.example", "make.globals", "repos.conf"),
            ),
            ("share/portage/config/sets", "cnf/sets", ("*.conf",)),
            ("share/man/man1", "man", ("*.1",)),
            ("share/man/man5", "man", ("*.5",)),
            ("share/portage/doc", "", ("NEWS", "RELEASE-NOTES")),
            ("lib/portage/bin", "bin", ("-m0755",)),
        ],
    ),
    entry_points={
        "console_scripts": [
            "{}=portage.util.bin_entry_point:bin_entry_point".format(
                os.path.basename(path)
            )
            for path in itertools.chain.from_iterable(x_scripts.values())
        ],
    }
    if create_entry_points
    else {},
    # create_entry_points disables ext_modules, for pure python
    ext_modules=[]
    if create_entry_points
    else [
        Extension(
            name=n,
            sources=m,
            extra_compile_args=[
                "-D_FILE_OFFSET_BITS=64",
                "-D_LARGEFILE_SOURCE",
                "-D_LARGEFILE64_SOURCE",
            ],
        )
        for n, m in x_c_helpers.items()
    ],
    cmdclass={
        "build": x_build,
        "build_ext": build_ext,
        "build_man": build_man,
        "build_scripts": x_build_scripts,
        "build_scripts_bin": x_build_scripts_bin,
        "build_scripts_portagebin": x_build_scripts_portagebin,
        "build_scripts_sbin": x_build_scripts_sbin,
        "build_tests": build_tests,
        "clean": x_clean,
        "docbook": docbook,
        "apidoc": apidoc,
        "install": x_install,
        "install_data": x_install_data,
        "install_docbook": install_docbook,
        "install_apidoc": install_apidoc,
        "install_lib": x_install_lib,
        "install_scripts": x_install_scripts,
        "install_scripts_bin": x_install_scripts_bin,
        "install_scripts_portagebin": x_install_scripts_portagebin,
        "install_scripts_sbin": x_install_scripts_sbin,
        "sdist": x_sdist,
        "test": test,
    },
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Environment :: Console",
        "Intended Audience :: System Administrators",
        "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
        "Operating System :: POSIX",
        "Programming Language :: Python :: 3",
        "Topic :: System :: Installation/Setup",
    ],
    python_requires=">=3.6",
)
