App-git-ship
view release on metacpan or search on metacpan
lib/App/git/ship.pm view on Meta::CPAN
# Need to be overridden in subclass
sub build { $_[0]->abort('build() is not available for %s', ref $_[0]) }
sub can_handle_project { $_[0]->abort('can_handle_project() is not available for %s', ref $_[0]) }
sub abort {
my ($self, $format, @args) = @_;
my $message = @args ? sprintf $format, @args : $format;
Carp::confess("!! $message") if DEBUG;
die "!! $message\n";
}
sub config {
my ($self, $key, $value) = @_;
my $config = $self->{config} ||= $self->_build_config;
# Get all
return $config if @_ == 1;
# Get single key
if (@_ == 2) {
return $config->{$key} if exists $config->{$key};
my $param_method = "_build_config_param_$key";
return $self->$param_method if $self->can($param_method);
my $env_key = uc "GIT_SHIP_$key";
return decode 'UTF-8', $ENV{$env_key} // '';
}
# Set single key
$config->{$key} = $value;
return $self;
}
sub detect {
my ($self, $file) = (@_, '');
if (my $class = $self->config('class')) {
$self->abort("Could not load $class: $@") unless eval "require $class;1";
return $class;
}
require Module::Find;
for my $class (sort { length $b <=> length $a } Module::Find::findallmod(__PACKAGE__)) {
eval "require $class;1" or next;
next unless $class->can('can_handle_project');
warn "[ship::detect] $class->can_handle_project($file)\n" if DEBUG;
return $class if $class->can_handle_project($file);
}
$self->abort("Could not figure out what kind of project this is from '$file'");
}
sub dump {
return Data::Dumper->new([$_[1]])->Indent(1)->Terse(1)->Sortkeys(1)->Dump;
}
sub new {
my $self = shift->SUPER::new(@_);
open $self->{STDOUT}, '>&STDOUT';
open $self->{STDERR}, '>&STDERR';
return $self;
}
sub render_template {
my ($self, $name, $args) = @_;
my $template = $self->_get_template($name) or $self->abort("Could not find template for $name");
# Render to string
return $template->process({%$args, ship => $self}) if $args->{to_string};
# Render to file
my $file = path split '/', $name;
if (-e $file and !$args->{force}) {
say "# $file exists" unless SILENT;
return $self;
}
# Try to read template from $HOME/$name
if ($args->{template_from_home}) {
my $src = $ENV{HOME} ? path $ENV{HOME}, $name : undef $template->parse($file->slurp)
if $file and -r $file;
}
$file->dirname->make_path unless -d $file->dirname;
$file->spurt(encode 'UTF-8', $template->process({%$args, ship => $self}));
say "# Generated $file" unless SILENT;
return $self;
}
sub run_hook {
my ($self, $name) = @_;
my $cmd = $self->config($name) or return;
$self->system($cmd);
}
sub ship {
my $self = shift;
my ($branch) = qx(git branch --no-color) =~ /\* (.+)$/m;
my ($remote) = qx(git remote -v) =~ /^origin\s+(.+)\s+\(push\)$/m;
$self->abort("Cannot ship without a current branch") unless $branch;
$self->abort("Cannot ship without a version number") unless $self->config('next_version');
$self->system(qw(git push origin), $branch) if $remote;
$self->system(qw(git tag) => $self->config('next_version'));
$self->system(qw(git push --tags origin)) if $remote;
}
sub start {
my $self = shift;
if (@_ and ref($self) eq __PACKAGE__) {
return $self->detect($_[0])->new($self)->start(@_);
}
$self->system(qw(git init-db)) unless -d '.git' and @_;
$self->render_template('.gitignore');
$self->system(qw(git add .));
$self->system(qw(git commit -a -m), "git ship start") if @_;
( run in 0.867 second using v1.01-cache-2.11-cpan-98e64b0badf )