<commit_before>"""The main program"""
import os
import sys
import errno
import string
import getpass
import datetime
import logging
import logging.config
from configparser import NoSectionError, NoOptionError

import click
from acme import errors as acme_errors

from . import config
from . import cert
from . import utils
from . import ca
from . import lb
from . import plugin
from . import version
from .vendor import click_spinner

# pylint: disable=W0613

logger = logging.getLogger(__name__)


def partition_completer(ctx, args, incomplete):
    # disable logging  so we don't spam
    # stdout with logging if something goes
    # kinda wrong
    logging.disable(60)
    try:
        all_certs = cert.get_all_certs()
        partitions = set(
            [x.partition for x in all_certs if x.partition.startswith(incomplete)]
        )
        return sorted(partitions)
    except:
        return []


def csrname_completer(ctx, args, incomplete):
    # disable logging  so we don't spam
    # stdout with logging if something goes
    # kinda wrong
    logging.disable(60)
    try:
        all_certs = cert.get_all_certs()
        partition = args[-1]
        return sorted(
            [
                cert.name
                for cert in all_certs
                if cert.partition == partition and cert.name.startswith(incomplete)
            ]
        )
    except:
        return []


def need_configuration(need_account=True):
    """
    Decorator for functions that need the configuration files.
    """

    def config_decorator(func):
        def wrapper(*args, **kwargs):
            if not config.check_configfiles():
                click.secho(
                    "Could not find the configuration files in the specified folder.",
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            if need_account:
                if not config.check_account_file():
                    click.secho(
                        "Could not find an account. You must register with the CA.",
                        fg="red",
                        err=True,
                    )
                    sys.exit(1)
            try:
                the_config = config.read_configfile()
            except (NoSectionError, NoOptionError, ValueError) as error:
                click.secho(
                    f"The configuration files was found, but was not complete: {error}",
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            kwargs.update({"configuration": the_config})

            logging.config.fileConfig(
                config.LOG_CONFIG_FILE, disable_existing_loggers=False
            )
            func(*args, **kwargs)

        return wrapper

    return config_decorator


def handle_exceptions(func):
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except RuntimeError:
            # Click abort inherits
            # from RuntimeError.
            raise
        except Exception as error:
            logger.exception("An unexpected error occured")
            click.secho(f"An unexpected error occured: {error}", fg="red", err=True)
            sys.exit(1)

    return wrapper


@click.group(context_settings={"help_option_names": ["-h", "--help"]})
@click.option(
    "--config-dir",
    default=".",
    help="The config dir to use. Defaults to the current folder.",
    type=click.Path(),
)
def cli(config_dir):
    """
    The main CLI. Only changes the current cirectory to the config dir,
    everything else is handles by the commands.
    """
    try:
        os.chdir(os.path.abspath(config_dir))
    except OSError as error:
        if error.errno == 2:
            click.secho(
                f"Could not locate the specified configuration folder.",
                fg="red",
                err=True,
            )
            sys.exit(1)<commit_msg>Somebody forgot that the docstring is used in the CLI<commit_after>"""The main program"""
import os
import sys
import errno
import string
import getpass
import datetime
import logging
import logging.config
from configparser import NoSectionError, NoOptionError

import click
from acme import errors as acme_errors

from . import config
from . import cert
from . import utils
from . import ca
from . import lb
from . import plugin
from . import version
from .vendor import click_spinner

# pylint: disable=W0613

logger = logging.getLogger(__name__)


def partition_completer(ctx, args, incomplete):
    # disable logging  so we don't spam
    # stdout with logging if something goes
    # kinda wrong
    logging.disable(60)
    try:
        all_certs = cert.get_all_certs()
        partitions = set(
            [x.partition for x in all_certs if x.partition.startswith(incomplete)]
        )
        return sorted(partitions)
    except:
        return []


def csrname_completer(ctx, args, incomplete):
    # disable logging  so we don't spam
    # stdout with logging if something goes
    # kinda wrong
    logging.disable(60)
    try:
        all_certs = cert.get_all_certs()
        partition = args[-1]
        return sorted(
            [
                cert.name
                for cert in all_certs
                if cert.partition == partition and cert.name.startswith(incomplete)
            ]
        )
    except:
        return []


def need_configuration(need_account=True):
    """
    Decorator for functions that need the configuration files.
    """

    def config_decorator(func):
        def wrapper(*args, **kwargs):
            if not config.check_configfiles():
                click.secho(
                    "Could not find the configuration files in the specified folder.",
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            if need_account:
                if not config.check_account_file():
                    click.secho(
                        "Could not find an account. You must register with the CA.",
                        fg="red",
                        err=True,
                    )
                    sys.exit(1)
            try:
                the_config = config.read_configfile()
            except (NoSectionError, NoOptionError, ValueError) as error:
                click.secho(
                    f"The configuration files was found, but was not complete: {error}",
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            kwargs.update({"configuration": the_config})

            logging.config.fileConfig(
                config.LOG_CONFIG_FILE, disable_existing_loggers=False
            )
            func(*args, **kwargs)

        return wrapper

    return config_decorator


def handle_exceptions(func):
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except RuntimeError:
            # Click abort inherits
            # from RuntimeError.
            raise
        except Exception as error:
            logger.exception("An unexpected error occured")
            click.secho(f"An unexpected error occured: {error}", fg="red", err=True)
            sys.exit(1)

    return wrapper


@click.group(context_settings={"help_option_names": ["-h", "--help"]})
@click.option(
    "--config-dir",
    default=".",
    help="The config dir to use. Defaults to the current folder.",
    type=click.Path(),
)
def cli(config_dir):
    """ACME client for Big-IP"""
    try:
        os.chdir(os.path.abspath(config_dir))
    except OSError as error:
        if error.errno == 2:
            click.secho(
                f"Could not locate the specified configuration folder.",
                fg="red",
                err=True,
            )
            sys.exit(1)
{'fraction_non_alphanumeric': 0.08580521960534691, 'fraction_numerical': 0.0038192234245703373, 'mean_word_length': 1.7584269662921348, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2705398', 'n_tokens_mistral': 2139, 'n_tokens_neox': 2019, 'n_words': 617}