<commit_before>"""
This is where the mainline sits and is responsible for setting up the logging,
the argument parsing and for starting up Harpoon.
"""

from harpoon.errors import BadDockerConnection
from harpoon.collector import Collector

from input_algorithms.spec_base import NotSpecified
from docker.client import Client as DockerClient
from delfick_app import App, DelayedFileType
from docker.utils import kwargs_from_env
import requests
import logging
import os

log = logging.getLogger("harpoon.executor")

def docker_context():
    """Make a docker context"""
    options = kwargs_from_env(assert_hostname=False)
    options["version"] = "auto"
    options["timeout"] = int(os.environ.get("DOCKER_CLIENT_TIMEOUT", 180))

    client = DockerClient(**options)
    try:
        info = client.info()
        log.info("Connected to docker daemon\tdriver=%s\tkernel=%s", info["Driver"], info["KernelVersion"])
    except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as error:
        raise BadDockerConnection(base_url=options.get('base_url'), error=error)
    return client

class App(App):
    cli_categories = ['harpoon']
    cli_description = "Docker client that reads yaml"
    cli_environment_defaults = {"HARPOON_CONFIG": ("--harpoon-config", './harpoon.yml')}
    cli_positional_replacements = [('--task', 'list_tasks'), ('--image', NotSpecified)]

    def execute(self, args, extra_args, cli_args, logging_handler, no_docker=False):
        cli_args["harpoon"]["config"] = cli_args["harpoon"]["config"]()
        cli_args["harpoon"]["extra"] = extra_args

        if not no_docker:
            cli_args["harpoon"]["docker_context"] = docker_context()
        cli_args["harpoon"]["docker_context_maker"] = docker_context

        for key in ('bash', 'command'):
            if cli_args[key] is None:
                cli_args[key] = NotSpecified

        collector = Collector()
        collector.prepare(cli_args["harpoon"]["config"].name, cli_args)
        if "term_colors" in collector.configuration:
            self.setup_logging_theme(logging_handler, colors=collector.configuration["term_colors"])

        collector.configuration["task_runner"](collector.configuration["harpoon"].chosen_task)

    def setup_other_logging(self, args, verbose=False, silent=False, debug=False):
        logging.getLogger("requests").setLevel([logging.CRITICAL, logging.ERROR][verbose or debug])

    def specify_other_args(self, parser, defaults):
        parser.add_argument("--harpoon-config"
            , help = "The config file specifying what harpoon should care about"
            , type = DelayedFileType("r")
            , **defaults["--harpoon-config"]
            )

        parser.add_argument("--dry-run"
            , help = "Should Harpoon take any real action or print out what is intends to do"
            , dest = "harpoon_dry_run"
            , action = "store_true"<commit_msg>Add --version<commit_after>"""
This is where the mainline sits and is responsible for setting up the logging,
the argument parsing and for starting up Harpoon.
"""

from harpoon.errors import BadDockerConnection
from harpoon.collector import Collector
from harpoon import VERSION

from input_algorithms.spec_base import NotSpecified
from docker.client import Client as DockerClient
from delfick_app import App, DelayedFileType
from docker.utils import kwargs_from_env
import requests
import logging
import os

log = logging.getLogger("harpoon.executor")

def docker_context():
    """Make a docker context"""
    options = kwargs_from_env(assert_hostname=False)
    options["version"] = "auto"
    options["timeout"] = int(os.environ.get("DOCKER_CLIENT_TIMEOUT", 180))

    client = DockerClient(**options)
    try:
        info = client.info()
        log.info("Connected to docker daemon\tdriver=%s\tkernel=%s", info["Driver"], info["KernelVersion"])
    except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as error:
        raise BadDockerConnection(base_url=options.get('base_url'), error=error)
    return client

class App(App):
    cli_categories = ['harpoon']
    cli_description = "Docker client that reads yaml"
    cli_environment_defaults = {"HARPOON_CONFIG": ("--harpoon-config", './harpoon.yml')}
    cli_positional_replacements = [('--task', 'list_tasks'), ('--image', NotSpecified)]

    def execute(self, args, extra_args, cli_args, logging_handler, no_docker=False):
        if args.version:
            print(VERSION)
            return

        cli_args["harpoon"]["config"] = cli_args["harpoon"]["config"]()
        cli_args["harpoon"]["extra"] = extra_args

        if not no_docker:
            cli_args["harpoon"]["docker_context"] = docker_context()
        cli_args["harpoon"]["docker_context_maker"] = docker_context

        for key in ('bash', 'command'):
            if cli_args[key] is None:
                cli_args[key] = NotSpecified

        collector = Collector()
        collector.prepare(cli_args["harpoon"]["config"].name, cli_args)
        if "term_colors" in collector.configuration:
            self.setup_logging_theme(logging_handler, colors=collector.configuration["term_colors"])

        collector.configuration["task_runner"](collector.configuration["harpoon"].chosen_task)

    def setup_other_logging(self, args, verbose=False, silent=False, debug=False):
        logging.getLogger("requests").setLevel([logging.CRITICAL, logging.ERROR][verbose or debug])

    def specify_other_args(self, parser, defaults):
        parser.add_argument("--harpoon-config"
            , help = "The config file specifying what harpoon should care about"
            , type = DelayedFileType("r")
            , **defaults["--harpoon-config"]
            )

        parser.add_argument("--version"
            , help = "Print out the version of harpoon"
            , action = "store_true"
            )

        parser.add_argument("--dry-run"
            , help = "Should Harpoon take any real action or print out what is intends to do"
            , dest = "harpoon_dry_run"
            , action = "store_true"
{'fraction_non_alphanumeric': 0.11812058485296534, 'fraction_numerical': 0.0009857072449482504, 'mean_word_length': 3.587792012057272, 'pattern_counts': {'":': 2, '<': 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': '3175101', 'n_tokens_mistral': 1796, 'n_tokens_neox': 1760, 'n_words': 416}