<commit_before>import logging
import os
import subprocess
from types import SimpleNamespace

import click

# The "cc" command requires a build-dir parameter
# that it adds to the context for subcommand to use.
from click import UsageError

from leosacpy.utils import get_docker_client, guess_root_dir


# Commands in this file are added manually
# in dev.py


@click.group()
@click.pass_context
@click.option('--build-dir',
              type=str,
              nargs=1,
              help='Directory that will be mounted as build root. '
                   'Defaults to /tmp/leosac_cc_build')
def cc(ctx, build_dir):
    """
    The cc (cross-compile) command is a frontend to the
    leosac_cross_compile container.
    """
    ctx.obj.cc = SimpleNamespace()

    if build_dir is None:
        build_dir = '/tmp/leosac_cc_build'
        try:
            os.mkdir(build_dir)
        except FileExistsError:
            pass

    abs_build_dir = os.path.abspath(build_dir)
    if not os.path.isdir(build_dir):
        raise UsageError(
            'Specified build directory {} is not valid.'.format(abs_build_dir))

    ctx.obj.cc.build_dir = abs_build_dir


def run_in_container(build_dir, repo_root_dir, command,
                     deploy_key=None):
    """
    Run `command` in cross_compile container.
    :return: The return code of the container.
    """
    assert isinstance(build_dir, str)
    assert isinstance(repo_root_dir, str)
    assert isinstance(command, (list, str)), 'Is {} instead'.format(type(command))

    volumes_cfg = {
        build_dir: {
            'bind': '/leosac_arm_build',
            'mode': 'rw'
        },
        repo_root_dir: {
            'bind': '/leosac',
            'mode': 'ro'
        }
    }

    if deploy_key:
        volumes_cfg[deploy_key] = {
            'bind': '/ssh_deploy_key',
            'mode': 'ro'
        }

    c = get_docker_client().containers.run('leosac_cross_compile',
                                           '"' + command + '"',
                                           volumes=volumes_cfg,
                                           detach=True,
                                           entrypoint=['/bin/bash', '-c'])
    print('Build output:')
    for log_line in c.logs(stream=True, stdout=True, stderr=True):
        print(log_line.decode('utf8'), end='')

    # Wait for container to stop, and return container's return code
    while not c.status == 'exited':
        c.reload()
    return c.attrs['State']['ExitCode']


@cc.command()
@click.pass_context
def cmake(ctx):
    """
    Run the CMake command to prepare the build
    directory.
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    run_in_container(build_dir, guess_root_dir(),
                     'cd /leosac_arm_build; '
                     'cmake -DCMAKE_SYSROOT=/opt/rpi_fakeroot '
                     '-DCMAKE_BUILD_TYPE=Debug  '
                     '-DCMAKE_TOOLCHAIN_FILE=/leosac/cmake/rpi-cross.cmake /leosac')


@cc.command()
@click.option('--job', '-j',
              type=int,
              help='Number of make job.')
@click.pass_context
def make(ctx, job):
    """
    Run `make` to build Leosac.
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    nb_job = job or 4
    x = run_in_container(build_dir, guess_root_dir(),
                         'cd /leosac_arm_build && make -j{}'.format(nb_job))
    if x != 0:
        raise SystemExit("Docker container exited with return code {}".format(x))


@cc.command(name='dev-push',
            short_help='Deploy build to remote host.')
@click.option('--host', '-h', required=True,
              help='Address of the remote host')
@click.option('--directory', '-d', required=True,
              help='Target directory on the remote host.')
@click.option('--key', '-k',
              help='Path to the SSH key to connect to host. Defaults to '
                   '$HOME/.ssh/id_rsa')
@click.option('--user', '-u',
              help='SSH user to log with. Defaults to root.')
@click.pass_context
def dev_push(ctx, host, directory, key, user):
    """
    Deploy (SCP) the build binaries to a given host.
    Note that only Leosac binary and libraries are pushed, not cross-compiled
    system libraries.
    """
    build_dir = ctx.obj.cc.build_dir

    if not key:
        key = '{}/.ssh/id_rsa'.format(os.environ['HOME'])
    if not user:
        user = 'root'

    opt = '-a --delete -r -v -e \\"ssh -o StrictHostKeyChecking=no -i /ssh_deploy_key\\" '
    cmd = 'rsync {} /leosac_arm_build/*.so /leosac_arm_build/leosac {}@{}:{}'. \
        format(opt, user, host, directory)
    run_in_container(build_dir, guess_root_dir(), cmd, deploy_key=key)


@cc.command('fakeroot-package')
@click.pass_context
def fakeroot(ctx):
    """
    Make a tarball of fakeroot (fixed after container is built)
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    # Copy current libstdc++ to the fakeroot
    add_libstd_cmd = 'cp /usr/arm-linux-gnueabihf/lib/libstdc++.so.6.0.22 ' \
                     '/opt/rpi_fakeroot/lib && ' \
                     'ln -s /opt/rpi_fakeroot/lib/libstdc++.so.6.0.22 ' \
                     '/opt/rpi_fakeroot/lib/libstdc++.so.6 '
    tar_cmd = 'tar cvf /leosac_arm_build/fakeroot.tar /opt/rpi_fakeroot'
    cmd = add_libstd_cmd + ' && ' + tar_cmd
    run_in_container(build_dir, guess_root_dir(), cmd)


@cc.command('package')
@click.pass_context
def package(ctx):
    build_dir = ctx.obj.cc.build_dir

    run_in_container(build_dir, guess_root_dir(),
                     'cd /leosac_arm_build && make package')
<commit_msg>Hackfix for cross-compilation through docker<commit_after>import logging
import os
import subprocess
from types import SimpleNamespace

import click

# The "cc" command requires a build-dir parameter
# that it adds to the context for subcommand to use.
from click import UsageError

from leosacpy.utils import get_docker_client, guess_root_dir


# Commands in this file are added manually
# in dev.py


@click.group()
@click.pass_context
@click.option('--build-dir',
              type=str,
              nargs=1,
              help='Directory that will be mounted as build root. '
                   'Defaults to /tmp/leosac_cc_build')
def cc(ctx, build_dir):
    """
    The cc (cross-compile) command is a frontend to the
    leosac_cross_compile container.
    """
    ctx.obj.cc = SimpleNamespace()

    if build_dir is None:
        build_dir = '/tmp/leosac_cc_build'
        try:
            os.mkdir(build_dir)
        except FileExistsError:
            pass

    abs_build_dir = os.path.abspath(build_dir)
    if not os.path.isdir(build_dir):
        raise UsageError(
            'Specified build directory {} is not valid.'.format(abs_build_dir))

    ctx.obj.cc.build_dir = abs_build_dir


def run_in_container(build_dir, repo_root_dir, command,
                     deploy_key=None):
    """
    Run `command` in cross_compile container.
    :return: The return code of the container.
    """
    assert isinstance(build_dir, str)
    assert isinstance(repo_root_dir, str)
    assert isinstance(command, (list, str)), 'Is {} instead'.format(type(command))

    volumes_cfg = {
        build_dir: {
            'bind': '/leosac_arm_build',
            'mode': 'rw'
        },
        repo_root_dir: {
            'bind': '/leosac',
            'mode': 'rw'
        }
    }

    if deploy_key:
        volumes_cfg[deploy_key] = {
            'bind': '/ssh_deploy_key',
            'mode': 'ro'
        }

    c = get_docker_client().containers.run('leosac_cross_compile',
                                           '"' + command + '"',
                                           volumes=volumes_cfg,
                                           detach=True,
                                           entrypoint=['/bin/bash', '-c'])
    print('Build output:')
    for log_line in c.logs(stream=True, stdout=True, stderr=True):
        print(log_line.decode('utf8'), end='')

    # Wait for container to stop, and return container's return code
    while not c.status == 'exited':
        c.reload()
    return c.attrs['State']['ExitCode']


@cc.command()
@click.pass_context
def cmake(ctx):
    """
    Run the CMake command to prepare the build
    directory.
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    run_in_container(build_dir, guess_root_dir(),
                     'cd /leosac_arm_build; '
                     'cmake -DCMAKE_SYSROOT=/opt/rpi_fakeroot '
                     '-DCMAKE_BUILD_TYPE=Debug  '
                     '-DCMAKE_TOOLCHAIN_FILE=/leosac/cmake/rpi-cross.cmake /leosac')


@cc.command()
@click.option('--job', '-j',
              type=int,
              help='Number of make job.')
@click.pass_context
def make(ctx, job):
    """
    Run `make` to build Leosac.
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    nb_job = job or 4
    x = run_in_container(build_dir, guess_root_dir(),
                         'cd /leosac_arm_build && make -j{}'.format(nb_job))
    if x != 0:
        raise SystemExit("Docker container exited with return code {}".format(x))


@cc.command(name='dev-push',
            short_help='Deploy build to remote host.')
@click.option('--host', '-h', required=True,
              help='Address of the remote host')
@click.option('--directory', '-d', required=True,
              help='Target directory on the remote host.')
@click.option('--key', '-k',
              help='Path to the SSH key to connect to host. Defaults to '
                   '$HOME/.ssh/id_rsa')
@click.option('--user', '-u',
              help='SSH user to log with. Defaults to root.')
@click.pass_context
def dev_push(ctx, host, directory, key, user):
    """
    Deploy (SCP) the build binaries to a given host.
    Note that only Leosac binary and libraries are pushed, not cross-compiled
    system libraries.
    """
    build_dir = ctx.obj.cc.build_dir

    if not key:
        key = '{}/.ssh/id_rsa'.format(os.environ['HOME'])
    if not user:
        user = 'root'

    opt = '-a --delete -r -v -e \\"ssh -o StrictHostKeyChecking=no -i /ssh_deploy_key\\" '
    cmd = 'rsync {} /leosac_arm_build/*.so /leosac_arm_build/leosac {}@{}:{}'. \
        format(opt, user, host, directory)
    run_in_container(build_dir, guess_root_dir(), cmd, deploy_key=key)


@cc.command('fakeroot-package')
@click.pass_context
def fakeroot(ctx):
    """
    Make a tarball of fakeroot (fixed after container is built)
    """
    build_dir = ctx.obj.cc.build_dir
    assert isinstance(build_dir, str)

    # Copy current libstdc++ to the fakeroot
    add_libstd_cmd = 'cp /usr/arm-linux-gnueabihf/lib/libstdc++.so.6.0.22 ' \
                     '/opt/rpi_fakeroot/lib && ' \
                     'ln -s /opt/rpi_fakeroot/lib/libstdc++.so.6.0.22 ' \
                     '/opt/rpi_fakeroot/lib/libstdc++.so.6 '
    tar_cmd = 'tar cvf /leosac_arm_build/fakeroot.tar /opt/rpi_fakeroot'
    cmd = add_libstd_cmd + ' && ' + tar_cmd
    run_in_container(build_dir, guess_root_dir(), cmd)


@cc.command('package')
@click.pass_context
def package(ctx):
    build_dir = ctx.obj.cc.build_dir

    run_in_container(build_dir, guess_root_dir(),
                     'cd /leosac_arm_build && make package')

{'fraction_non_alphanumeric': 0.12562725592041554, 'fraction_numerical': 0.00228893388502509, 'mean_word_length': 2.20360970107163, 'pattern_counts': {'":': 0, '<': 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': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5874381', 'n_tokens_mistral': 3731, 'n_tokens_neox': 3605, 'n_words': 852}