<commit_before>package App::PocketPaas::App;

use strict;
use warnings;

use App::PocketPaas::Docker qw(
    docker_attach docker_build docker_commit docker_containers docker_images
    docker_rm docker_rmi docker_run docker_stop docker_wait
);
use App::PocketPaas::Hipache qw(add_hipache_app);
use App::PocketPaas::Model::App;
use App::PocketPaas::Notes qw(add_note delete_note);
use App::PocketPaas::Util qw(next_tag);

use File::Path qw(make_path);
use File::Slurp qw(write_file);
use File::Temp qw(tempdir);
use IPC::Run3;
use Log::Log4perl qw(:easy);

use Sub::Exporter -setup =>
    { exports => [qw(push_app start_app stop_app destroy_app)] };

sub push_app {
    my ( $config, $app_config ) = @_;

    my $app_name = $app_config->{name};

    my $app = App::PocketPaas::Model::App->load(
        $config, $app_name,
        docker_containers( $config, { all => 1 } ),
        docker_images( $config, )
    );

    INFO("Pushing $app_name");

    my $app_build_dir = tempdir();

    DEBUG("App build dir: $app_build_dir");

    _generate_app_tarball($app_build_dir);

    prepare_app_build( $config, $app_build_dir, $app_name );

    my $tag = next_tag( $config, $app );

    if (docker_build(
            $config, $app_build_dir,
            "$config->{app_image_prefix}/$app_name:temp-$tag"
        )
        )
    {
        INFO("Application built successfully");
    }
    else {
        docker_rmi( $config,
            "$config->{app_image_prefix}/$app_name:temp-$tag" );
        return;
    }

    my %cache_volume_opts;
    if ( !$app_config->{'no_cache'} ) {
        my $cache_dir = "$config->{base_dir}/cache/$app_name";
        if ( $app_config->{'reset_cache'} ) {

            # TODO: remove cache path, might be root owned
        }
        make_path($cache_dir);

        %cache_volume_opts = ( volumes => ["$cache_dir:/cache"] );
    }

    INFO("Building application");
    if (my $build_container_id = docker_run(
            $config,
            "$config->{app_image_prefix}/$app_name:temp-$tag",
            {   daemon  => 1,
                command => '/build/builder',
                %cache_volume_opts
            }
        )
        )
    {
        INFO("App build container: $build_container_id");
        docker_attach( $config, $build_container_id );

        if ( docker_wait( $config, $build_container_id ) ) {
            docker_commit( $config, $build_container_id,
                "$config->{app_image_prefix}/$app_name", "build-$tag" );
        }
        else {
            # TODO: clean up images
            FATAL("Application build failed");
        }
    }
    else {
        return;
    }

    start_app( $config, $app_config, $tag, $app );

    docker_rmi( $config, "$config->{app_image_prefix}/$app_name:temp-$tag" );

}

sub start_app {
    my ( $config, $app_config, $tag, $app ) = @_;

    my $app_name = $app_config->{name};

    my $app_run_build_dir = tempdir();
    DEBUG("Run build dir: $app_run_build_dir");

    # TODO services are blank when not run from app dir,
    # perhaps record services in note
    my $service_env   = '';
    my $service_names = [];
    if ( $app_config->{services} ) {
        foreach my $service ( @{ $app_config->{services} } ) {
            my $name = $service->{name};
            my $type = $service->{type};

            # TODO add support for a git url as the type
            $service
                = App::PocketPaas::Service->provision_service( $name, $type );

            $service_env .= $service->env();

            push @$service_names, $name;
        }
    }

    prepare_run_build( $config, $app_run_build_dir, $app_name, $tag,
        $service_env );

    if (!docker_build(
            $config, $app_run_build_dir,
            "$config->{app_image_prefix}/$app_name:run-$tag"
        )
        )
    {
        return;
    }

    # now start it up (-:<commit_msg>missed one improperly called function<commit_after>package App::PocketPaas::App;

use strict;
use warnings;

use App::PocketPaas::Docker qw(
    docker_attach docker_build docker_commit docker_containers docker_images
    docker_rm docker_rmi docker_run docker_stop docker_wait
);
use App::PocketPaas::Hipache qw(add_hipache_app);
use App::PocketPaas::Model::App;
use App::PocketPaas::Notes qw(add_note delete_note);
use App::PocketPaas::Service qw(provision_service);
use App::PocketPaas::Util qw(next_tag);

use File::Path qw(make_path);
use File::Slurp qw(write_file);
use File::Temp qw(tempdir);
use IPC::Run3;
use Log::Log4perl qw(:easy);

use Sub::Exporter -setup =>
    { exports => [qw(push_app start_app stop_app destroy_app)] };

sub push_app {
    my ( $config, $app_config ) = @_;

    my $app_name = $app_config->{name};

    my $app = App::PocketPaas::Model::App->load(
        $config, $app_name,
        docker_containers( $config, { all => 1 } ),
        docker_images( $config, )
    );

    INFO("Pushing $app_name");

    my $app_build_dir = tempdir();

    DEBUG("App build dir: $app_build_dir");

    _generate_app_tarball($app_build_dir);

    prepare_app_build( $config, $app_build_dir, $app_name );

    my $tag = next_tag( $config, $app );

    if (docker_build(
            $config, $app_build_dir,
            "$config->{app_image_prefix}/$app_name:temp-$tag"
        )
        )
    {
        INFO("Application built successfully");
    }
    else {
        docker_rmi( $config,
            "$config->{app_image_prefix}/$app_name:temp-$tag" );
        return;
    }

    my %cache_volume_opts;
    if ( !$app_config->{'no_cache'} ) {
        my $cache_dir = "$config->{base_dir}/cache/$app_name";
        if ( $app_config->{'reset_cache'} ) {

            # TODO: remove cache path, might be root owned
        }
        make_path($cache_dir);

        %cache_volume_opts = ( volumes => ["$cache_dir:/cache"] );
    }

    INFO("Building application");
    if (my $build_container_id = docker_run(
            $config,
            "$config->{app_image_prefix}/$app_name:temp-$tag",
            {   daemon  => 1,
                command => '/build/builder',
                %cache_volume_opts
            }
        )
        )
    {
        INFO("App build container: $build_container_id");
        docker_attach( $config, $build_container_id );

        if ( docker_wait( $config, $build_container_id ) ) {
            docker_commit( $config, $build_container_id,
                "$config->{app_image_prefix}/$app_name", "build-$tag" );
        }
        else {
            # TODO: clean up images
            FATAL("Application build failed");
        }
    }
    else {
        return;
    }

    start_app( $config, $app_config, $tag, $app );

    docker_rmi( $config, "$config->{app_image_prefix}/$app_name:temp-$tag" );

}

sub start_app {
    my ( $config, $app_config, $tag, $app ) = @_;

    my $app_name = $app_config->{name};

    my $app_run_build_dir = tempdir();
    DEBUG("Run build dir: $app_run_build_dir");

    # TODO services are blank when not run from app dir,
    # perhaps record services in note
    my $service_env   = '';
    my $service_names = [];
    if ( $app_config->{services} ) {
        foreach my $service ( @{ $app_config->{services} } ) {
            my $name = $service->{name};
            my $type = $service->{type};

            # TODO add support for a git url as the type
            $service = provision_service( $config, $name, $type );

            $service_env .= $service->env();

            push @$service_names, $name;
        }
    }

    prepare_run_build( $config, $app_run_build_dir, $app_name, $tag,
        $service_env );

    if (!docker_build(
            $config, $app_run_build_dir,
            "$config->{app_image_prefix}/$app_name:run-$tag"
        )
        )
    {
        return;
    }

    # now start it up (-:
{'fraction_non_alphanumeric': 0.14208563713514208, 'fraction_numerical': 0.0010286742960010286, 'mean_word_length': 2.4723214285714286, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 50, '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': '1971784', 'n_tokens_mistral': 2690, 'n_tokens_neox': 2570, 'n_words': 518}