App-Seacan

 view release on metacpan or  search on metacpan

lib/App/Seacan.pm  view on Meta::CPAN


sub perl_is_installed {
    my $self = shift;
    my $perlbrew_root_path = join_path($self->config->{seacan}{output}, "perlbrew");
    return 0 unless -d $perlbrew_root_path;
    my $perl_executable = join_path($perlbrew_root_path, "perls", $self->config->{perl}{installed_as}, "bin", "perl");
    if (my $r = -f $perl_executable) {
        say STDERR "perl is installed: $perl_executable";
        return 1;
    }
    return 0;
}

sub install_perl {
    my $self = shift;

    my $perlbrew_root_path = $self->seacan_perlbrew_root;
    make_path( $perlbrew_root_path ) unless -d $perlbrew_root_path;

    for (keys %ENV) {
        delete $ENV{$_} if /\APERLBREW_/;
    }
    delete $ENV{PERL_CPANM_OPT};
    delete $ENV{PERL_LOCAL_LIB_ROOT};
    delete $ENV{PERL_MB_OPT};
    delete $ENV{PERL_MM_OPT};
    delete $ENV{PERL5LIB};

    $ENV{PERLBREW_ROOT} = $perlbrew_root_path;

    system("curl -L https://install.perlbrew.pl | bash") == 0 or die $!;
    my $perlbrew_command = join_path($perlbrew_root_path, "bin", "perlbrew");
    system($perlbrew_command, "install", $self->config->{perl}{version}, "--as", $self->config->{perl}{installed_as}) == 0 or die $!;
    system($perlbrew_command, "install-cpanm", "--force");
}

sub install_cpan {
    my $self = shift;
    my $cpanm_command = join_path( $self->seacan_perlbrew_root, "bin", "cpanm");
    my $perl_command = $self->seacan_perl;

    $, = " ";
    system($perl_command, $cpanm_command, "--notest", "-L", join_path($self->config->{seacan}{output}, "local"), "--installdeps", $self->config->{seacan}{app} ) == 0 or die $!;
}

sub copy_app {
    my $self = shift;
    my $target_directory = join_path($self->config->{seacan}{output}, "app");
    my $source_directory = $self->config->{seacan}{app};

    make_path($target_directory);
    $source_directory =~ s{/+$}{};

    system("rsync", "-8vPa", $source_directory, $target_directory) == 0 or die;
}

sub create_launcher {
    # Instead of giving a very long command to the user
    # a launcher script is generated.
    # app_name and main_script could be added to the configuration
    # so we can add the info directly instead of "guessing" it
    # through a regex.

    my $self = shift;
    my $output = $self->config->{seacan}{output};

    # The launcher script goes into bin of the target directory
    my $target_directory = join_path($output, 'bin');

    my $app_name = $self->config->{seacan}{app_name};
    if ( !$app_name ) {
        # This is a hack to determine the application name from the
        # output value of the config in case it wasn't provided

        $app_name = $output;
        $app_name =~ s/^.+\/(.+?)$/$1/;
    }

    # Apps following the CPAN guidelines have a lib directory with the
    # modules. Adding this to the PERL5LIB allows to run this distributions
    # without installing them.
    my $app_lib =  join_path($output, 'app', $app_name, 'lib');
    my $launcher = join_path($target_directory, $app_name);
    make_path($target_directory);
    open(my $fh, ">:utf8", $launcher) or die $!;
    print $fh "#!/bin/bash\n";
    print $fh "PERL5LIB=$output/local/lib/perl5:$app_lib\n";
    print $fh "export PERL5LIB\n";
    # String "app" shouldn't be hardcoded and be part of the config
    # app.pl will not be the likely name of the main script.
    print $fh "$output/perlbrew/perls/seacan/bin/perl $output/app/$app_name/bin/$app_name \$@\n";
    close $fh or die($!);
    chmod(0755, $launcher) or die($!);
}

sub run {
    my $self = shift;
    $self->install_perl unless $self->perl_is_installed;
    $self->install_cpan;
    $self->copy_app;
    $self->create_launcher;
}

1;

=encoding utf-8

=head1 NAME

Seacan - A tool to prepare a self-contained app directory.

=head1 DESCRIPTION

Read the README file for now. L<https://github.com/gugod/Seacan/blob/master/README.md>

=head1 COPYRIGHT

Copyright (c) 2016 Kang-min Liu C<< <gugod@gugod.org> >>.

=head1 LICENCE



( run in 1.589 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )