Mojolicious-Command-deploy-heroku
view release on metacpan or search on metacpan
lib/Mojolicious/Command/deploy/heroku.pm view on Meta::CPAN
package Mojolicious::Command::deploy::heroku;
use Mojo::Base 'Mojolicious::Command';
#use IO::All 'io';
use File::Path 'make_path';
use File::Slurp qw/ slurp write_file /;
use File::Spec;
use Getopt::Long qw/ GetOptions :config no_auto_abbrev no_ignore_case /;
use IPC::Cmd 'can_run';
use Mojo::IOLoop;
use Mojo::UserAgent;
use Mojolicious::Command::generate::heroku;
use Mojolicious::Command::generate::makefile;
use Net::Heroku;
our $VERSION = 0.11;
has tmpdir => sub { $ENV{MOJO_TMPDIR} || File::Spec->tmpdir };
has ua => sub { Mojo::UserAgent->new->ioloop(Mojo::IOLoop->singleton) };
has description => "Deploy Mojolicious app to Heroku.\n";
has opt => sub { {} };
has credentials_file => sub {"$ENV{HOME}/.heroku/credentials"};
has makefile => 'Makefile.PL';
has usage => <<"EOF";
usage: $0 deploy heroku [OPTIONS]
# Create new app with randomly selected name and deploy
$0 deploy heroku -c
# Deploy to specified app and deploy (creates app if it does not exist)
$0 deploy heroku -n friggin-ponycorns
These options are available:
-n, --appname <name> Specify app name for deployment
-a, --api-key <api_key> Heroku API key (read from ~/.heroku/credentials by default).
-c, --create Create app with randomly selected name
-v, --verbose Verbose output (heroku response, git output)
-h, --help This message
EOF
sub opt_spec {
my $self = shift;
my $opt = {};
return $opt
if GetOptions(
"appname|n=s" => sub { $opt->{name} = pop },
"api-key|a=s" => sub { $opt->{api_key} = pop },
"create|c" => sub { $opt->{create} = pop },
);
}
sub validate {
my $self = shift;
my $opt = shift;
my @errors =
map $_ . ' command not found' =>
grep !can_run($_) => qw/ git ssh ssh-keygen /;
# Create or appname
push @errors => '--create or --appname must be specified'
if !defined $opt->{create} and !defined $opt->{name};
return @errors;
}
sub run {
my $self = shift;
# App home dir
$self->ua->server->app($self->app);
my $home_dir = $self->ua->server->app->home->to_string;
# Command-line Options
my $opt = $self->opt_spec(@_);
# Validate
my @errors = $self->validate($opt);
die "\n" . join("\n" => @errors) . "\n" . $self->usage if @errors;
# Net::Heroku
my $h = $self->heroku_object($opt->{api_key} || $self->local_api_key);
# Prepare
$self->generate_makefile;
$self->generate_herokufile;
# SSH key permissions
if (!remote_key_match($h)) {
print "\nHeroku does not have any SSH keys stored for you.";
my ($file, $key) = create_or_get_key();
print "\nUploading SSH public key $file\n";
$h->add_key(key => $key);
}
# Create
my $res = verify_app(
$h,
config_app(
$h,
create_or_get_app($h, $opt),
{BUILDPACK_URL => 'http://github.com/tempire/perloku.git'}
)
);
print "Collecting all files in "
. $self->app->home . " ..."
. " (Ctrl-C to cancel)\n";
# Upload
push_repo(
fill_repo(
$self->create_repo($home_dir, $self->tmpdir),
$self->app->home->list_files
),
$res
);
}
sub prompt {
my ($message, @options) = @_;
print "\n$message\n";
for (my $i = 0; $i < @options; $i++) {
printf "\n%d) %s" => $i + 1, $options[$i];
}
print "\n\n> ";
my $response = <STDIN>;
chomp $response;
return ($response
&& $response =~ /^\d+$/
&& $response > 0
&& $response < @options + 1)
( run in 1.147 second using v1.01-cache-2.11-cpan-d8267643d1d )