#!/usr/bin/env perl
BEGIN { $INC{'Applify.pm'} = 'INCLUDED' }
BEGIN { $INC{'App/Mypp.pm'} = 'INCLUDED' }
CLOSURE_1: {
package Applify;
use File::Basename ();
use constant SUB_NAME_IS_AVAILABLE
    => $INC{'App/FatPacker/Trace.pm'} ? 0 # this will be true when running under "fatpack"
     : eval 'use Sub::Name; 1'        ? 1
     :                                  0;
our $VERSION = eval '0.0501';
our $PERLDOC = 'perldoc';
my $ANON = 1;
sub __new_sub {
    my($fqn, $code) = @_;
    no strict 'refs';
    return if *$fqn{CODE};
    *$fqn = SUB_NAME_IS_AVAILABLE ? Sub::Name::subname($fqn, $code) : $code;
}
sub option {
    my $self = shift;
    my $type = shift or die 'Usage: option $type => ...';
    my $name = shift or die 'Usage: option $type => $name => ...';
    my $documentation = shift or die 'Usage: option $type => $name => $documentation, ...';
    my($default, @args);
    if(@_ % 2) {
        $default = shift;
        @args = @_;
    }
    else {
        @args = @_;
    }
    push @{ $self->{options} }, {
        default => $default,
        @args,
        type => $type,
        name => $name,
        documentation => $documentation,
    };
    return $self;
}
sub documentation {
    return $_[0]->{documentation} if(@_ == 1);
    $_[0]->{documentation} = $_[1] or die 'Usage: documentation $file|$module_name;';
    return $_[0];
}
sub version {
    return $_[0]->{version} if(@_ == 1);
    $_[0]->{version} = $_[1] or die 'Usage: version $module_name|$num;';
    return $_[0];
}
sub extends {
    my $self = shift;
    $self->{extends} = [@_];
    return $self;
}
sub app {
    my($self, $code) = @_;
    my $app = {};
    my $parser = $self->_option_parser;
    my(@options_spec, $application_class);
    for my $option (@{ $self->{options} }) {
        my $switch = $self->_attr_to_option($option->{name});
        push @options_spec, $self->_calculate_option_spec($option);
        $app->{$switch} = $option->{default} if(exists $option->{default});
    }
    unless($parser->getoptions($app, @options_spec, $self->_default_options)) {
        $self->_exit(1);
    }
    if($app->{help}) {
        $self->print_help;
        $self->_exit('help');
    }
    elsif($app->{man}) {
        system $PERLDOC => $self->documentation;
        $self->_exit($? >> 8);
    }
    elsif($app->{version}) {
        $self->print_version;
        $self->_exit('version');
    }
    $application_class = $self->_generate_application_class($code);
    $app = $application_class->new({
                map { my $k = $self->_option_to_attr($_); $k => $app->{$_} } keys %$app,
            });
    return $app if(defined wantarray); # $app = do $script_file;
    $self->_exit($app->run(@ARGV));
}
sub _calculate_option_spec {
    my($self, $option) = @_;
    my $spec = $self->_attr_to_option($option->{name});
    if($option->{type} =~ /^(?:bool|flag)/i) { $spec .= '!' }
    elsif($option->{type} =~ /^inc/) { $spec .= '+' }
    elsif($option->{type} =~ /^str/) { $spec .= '=s' }
    elsif($option->{type} =~ /^int/i) { $spec .= '=i' }
    elsif($option->{type} =~ /^num/i) { $spec .= '=f' }
    elsif($option->{type} =~ /^file/) { $spec .= '=s' } # TODO
    elsif($option->{type} =~ /^dir/) { $spec .= '=s' } # TODO
    else { die 'Usage: option {bool|flag|inc|str|int|num|file|dir} ...' }
    if(my $n_of = $option->{n_of}) {
        $spec .= $n_of eq '@' ? $n_of : "{$n_of}";
        $option->{default} and ref $option->{default} ne 'ARRAY' and die 'Usage option ... default => [Need to be an array ref]';
        $option->{default} ||= [];
    }
    return $spec;
}
sub _default_options {
    my $self = shift;
    my @default;
    push @default, 'help';
    push @default, 'man'     if $self->documentation;
    push @default, 'version' if $self->version;
    return @default;
}
sub _generate_application_class {
    my($self, $code) = @_;
    my $application_class = $self->{caller}[1];
    my $extends = $self->{extends} || [];
    my @required;
    $application_class =~ s!\W!_!g;
    $application_class = join '::', ref($self), "__ANON__${ANON}__", $application_class;
    $ANON++;
    eval qq[
        package $application_class;
        use base qw/ @$extends /;
        1;
    ] or die "Failed to generate applicatin class: $@";
    {
        no strict 'refs';
        __new_sub "$application_class\::new" => sub { my $class = shift; bless shift, $class } unless grep { $_->can('new') } @$extends;
        __new_sub "$application_class\::_script" => sub { $self };
        __new_sub "$application_class\::run" => sub {
            my($app, @extra) = @_;
            if(@required = grep { not defined $app->{$_} } @required) {
                my $required = join ', ', map { '--' .$self->_attr_to_option($_) } @required;
                $app->_script->print_help;
                die "Required attribute missing: $required\n";
            }
            return $app->$code(@extra);
        };
        for('app', $self->{caller}[0]) {
            my $ns = \%{"$_\::"};
            for my $name (keys %$ns) {
                $self->{skip_subs}{$name} and next;
                my $code = *{$ns->{$name}}{CODE} or next;
                my $fqn = join '::', $application_class, $name;
                __new_sub $fqn => $code;
                delete $ns->{$name}; # may be a bit too destructive?
            }
        }
        for my $option (@{ $self->{options} }) {
            my $name = $option->{name};
            my $fqn = join '::', $application_class, $option->{name};
            __new_sub $fqn => sub { @_ == 2 and $_[0]->{$name} = $_[1]; $_[0]->{$name} };
            push @required, $name if $option->{required};
        }
    }
    return $application_class;
}
sub options { $_[0]->{options} }
sub _option_parser {
    $_[0]->{_option_parser} ||= do {
        require Getopt::Long;
        Getopt::Long::Parser->new(config => [ qw( no_auto_help no_auto_version pass_through ) ]);
    };
}
sub new {
    my($class, $args) = @_;
    my $self = bless $args, $class;
    $self->{options} ||= [];
    $self->{caller} or die 'Usage: $self->new({ caller => [...], ... })';
    return $self;
}
sub print_help {
    my $self = shift;
    my @options = @{ $self->{options} };
    my $width = 0;
    push @options, { name => '' };
    push @options, { name => 'help', documentation => 'Print this help text' };
    push @options, { name => 'man', documentation => 'Display manual for this application' } if($self->documentation);
    push @options, { name => 'version', documentation => 'Print application name and version' } if($self->version);
    push @options, { name => '' };
    $self->_print_synopsis;
    OPTION:
    for my $option (@options) {
        my $length = length $option->{name};
        $width = $length if($width < $length);
    }
    print "Usage:\n";
    OPTION:
    for my $option (@options) {
        my $name = $self->_attr_to_option($option->{name}) or do { print "\n"; next OPTION };
        printf(" %s --%-${width}s  %s\n",
            $option->{required} ? '*' : ' ',
            $name,
            $option->{documentation},
        );
    }
    return $self;
}
sub _print_synopsis {
    my $self = shift;
    my $documentation = $self->documentation or return;
    my $print;
    unless(-e $documentation) {
        eval "use $documentation; 1" or die "Could not load $documentation: $@";
        $documentation =~ s!::!/!g;
        $documentation = $INC{"$documentation.pm"};
    }
    open my $FH, '<', $documentation or die "Failed to read synopsis from $documentation: $@";
    while(<$FH>) {
        last if($print and /^=(?:cut|head1)/);
        print if($print);
        $print = 1 if(/^=head1 SYNOPSIS/);
    }
}
sub print_version {
    my $self = shift;
    my $version = $self->version or die 'Cannot print version without version()';
    unless($version =~ m!^\d!) {
        eval "require $version; 1" or die "Could not load $version: $@";
        $version = $version->VERSION;
    }
    printf "%s version %s\n", File::Basename::basename($0), $version;
}
sub _exit {
    my($self, $reason) = @_;
    exit 0 unless($reason =~ /^\d+$/); # may change without warning...
    exit $reason;
}
sub _attr_to_option {
    local $_ = $_[1] or return;
    s!_!-!g;
    $_;
}
sub _option_to_attr {
    local $_ = $_[1] or return;
    s!-!_!g;
    $_;
}
sub import {
    my $class = shift;
    my @caller = caller;
    my $self = $class->new({ caller => \@caller });
    my $ns = $caller[0] .'::';
    strict->import;
    warnings->import;
    $self->{skip_subs} = {
        app => 1,
        option => 1,
        version => 1,
        documentation => 1,
        extends => 1,
    };
    no strict 'refs';
    for my $name (keys %$ns) {
        $self->{'skip_subs'}{$name} = 1;
    }
    no warnings 'redefine'; # need to allow redefine when loading a new app
    *{"$caller[0]\::app"} = sub (&) { $self->app(@_) };
    *{"$caller[0]\::option"} = sub { $self->option(@_) };
    *{"$caller[0]\::version"} = sub { $self->version(@_) };
    *{"$caller[0]\::documentation"} = sub { $self->documentation(@_) };
    *{"$caller[0]\::extends"} = sub { $self->extends(@_) };
}
1;
}
CLOSURE_2: {
use Applify;
option bool => init => 'Alias for --update';
option str => update => 'Update repository files' => n_of => '0,';
option bool => test => 'Run unittests';
option bool => build => 'Build a distribution';
option bool => share => 'Push built distribution to CPAN and origin git repo';
option bool => clean => 'Remove generated files by make';
option bool => force => 'Force action, such as overwriting files';
version 'App::Mypp';
extends 'App::Mypp';
sub die_on_old_test_structure {
  die <<'NOTICE' unless $ENV{MYPP_KEEP_OLD_STRUCTURE}
You have an old t/ structure with 00-load.t, 00-pod.t and 00-pod-coverage.t
You should probably convert to t/00-basic.t. Do so by deleting the old
00-xxx.t tests and run "mypp" again.
You can also disable this message by setting the MYPP_KEEP_OLD_STRUCTURE
environment variable to true.
NOTICE
}
app {
    my $self = shift;
    my $action = shift || '__UNDEF__';
    if($action and $self->can($action)) {
        $self->$action($action eq 'update' ? [keys %{ $self->_templates }] : 1);
    }
    if(@{ $self->update } or $self->init) {
        $self->update([keys %{ $self->_templates }]) unless(grep { /\w/ } @{ $self->update });
        $self->_generate_file_from_template($_) for reverse sort @{ $self->update };
        $self->_system(sprintf '%s %s > %s', 'perldoc -tT', $self->top_module, 'README');
    }
    elsif($self->test) {
        if(-e 't/00-load.t') {
          $self->die_on_old_test_structure;
        }
        else {
          $self->_generate_file_from_template('t/00-basic.t');
        }
        $self->_make('clean');
        $self->_make('test');
    }
    elsif($self->build) {
        $self->_build;
    }
    elsif($self->share) {
        my $branch = (qx/git branch/ =~ /\* (.*)$/m)[0];
        chomp $branch;
        $self->_share_via_extension;
        $self->_git(push => origin => $branch);
        $self->_git(push => '--tags' => 'origin');
    }
    elsif($self->clean) {
        $self->_make('clean');
        unlink $_ for qw( Changes.old Makefile.old MANIFEST META.json META.yml );
        unlink $self->dist_file;
    }
    else {
        $self->_script->print_help;
    }
    return 0;
};
}
CLOSURE_3: {
package App::Mypp;
use Cwd;
use File::Basename;
use File::Find;
$ENV{HOME} ||= $ENV{USERPROFILE} || 'UNKNOWN';
our $VERSION = '0.1901';
our $SILENT = $ENV{MYPP_SILENT} || $ENV{SILENT} || 0;
our $PAUSE_FILENAME = $ENV{HOME} .'/.pause';
our $VERSION_RE = qr/\d+ \. [\d_]+/x;
open my $OLDOUT, '>&STDOUT';
open my $OLDERR, '>&STDERR';
sub _from_config ($&) {
    my($name, $sub) = @_;
    no strict 'refs';
    *$name = sub {
        my $self = shift;
        return $self->{$name} ||= $self->config->{$name} || $self->$sub(@_);
    };
}
sub _attr ($&) {
    my($name, $sub) = @_;
    no strict 'refs';
    *$name = sub {
        my $self = shift;
        return $self->{$name} ||= $self->$sub(@_);
    };
}
_attr config => sub {
    my $self = shift;
    my $file = $ENV{MYPP_CONFIG} || 'mypp.yml';
    my $config;
    unless(-e $file) {
        return {};
    }
    eval "use YAML::Tiny; 1;" or do {
        die <<"ERROR";
YAML::Tiny is not installed, meaning '$file' will not be read.
Use one of the commands below to install it:
\$ aptitude install libyaml-tiny-perl
\$ wget -q http://xrl.us/cpanm -O - | perl - YAML::Tiny
ERROR
    };
    $config = YAML::Tiny->read($file);
    return $config->[0] if $config and $config->[0];
    return {};
};
_from_config name => sub {
    my $self = shift;
    my $name;
    $name = join '-', split '/', $self->top_module;
    $name =~ s,^.?lib-,,;
    $name =~ s,\.pm$,,;
    return $name;
};
_from_config repository => sub {
    my $self = shift;
    my $repo = (qx( git remote show -n origin ) =~ /URL: (.*)$/m)[0];
    if($repo and $repo =~ /github/) {
      chomp $repo;
    }
    else {
      $repo = lc sprintf 'https://github.com/%s/%s', $ENV{USER} || 'your-username', $self->name;
    }
    $repo =~ s!git\@github\.com:(.*)!https://github.com/$1! and $repo =~ s!\.git$!!;
    $repo;
};
_from_config top_module => sub {
    my $self = shift;
    my $name = $self->config->{name} || basename getcwd;
    my @path = split /-/, $name;
    my $path = 'lib';
    my $file;
    for my $p (@path) {
        opendir my $DH, $path or die "Cannot find top module from project name '$name': $!\n";
        for my $f (readdir $DH) {
            $f =~ s/\.pm$//;
            if(lc $f eq lc $p) {
                $path = "$path/$f";
                last;
            }
        }
    }
    $path .= '.pm';
    unless(-f $path) {
        die "Cannot find top module from project name '$name': $path is not a plain file\n";
    }
    return $path;
};
_from_config top_module_name => sub {
    local $_ = $_[0]->top_module;
    s,\.pm,,; s,^/?lib/,,g; s,/,::,g;
    return $_;
};
_attr changes => sub {
    my $self = shift;
    my($text, $version);
    $self->_generate_file_from_template('Changes');
    open my $CHANGES, '<', 'Changes' or die "Read Changes: $!\n";
    while(<$CHANGES>) {
        if($text) {
            last if /^$/;
            $text .= $_;
        }
        elsif(/^($VERSION_RE)/) {
            $version = $1;
            $text = $_;
        }
    }
    unless($text and $version) {
        die "Could not find commit message nor version info from Changes\n";
    }
    return {
        text => $text,
        version => $version,
    };
};
_attr dist_file => sub {
    my $self = shift;
    return sprintf '%s-%s.tar.gz', $self->name, $self->changes->{version};
};
_attr pause_info => sub {
    open my $PAUSE, '<', $PAUSE_FILENAME or die "Read $PAUSE_FILENAME: $!\n";
    my %info = map { my($k, $v) = split /\s+/, $_, 2; chomp $v; ($k, $v) } <$PAUSE>;
    $info{user} or die "'user <name>' is not set in $PAUSE_FILENAME\n";
    $info{password} or die "'password <mysecret>' is not set in $PAUSE_FILENAME\n";
    return \%info;
};
_attr share_extension => sub {
    my $self = shift;
    return $ENV{MYPP_SHARE_MODULE} if($ENV{MYPP_SHARE_MODULE});
    return $self->config->{share_extension} if($self->config->{share_extension});
    return 'CPAN::Uploader';
};
_from_config share_params => sub {
    return;
};
sub force { shift->{force} || 0 }
my %TEMPLATES;
sub _templates {
    unless(%TEMPLATES) {
        my($key, $text);
        while(<DATA>) {
            if(/\%\% (\S+)/) {
                $TEMPLATES{$key} = $text if($key);
                $key = $1;
                $text = '';
            }
            else {
                $text .= $_;
            }
        }
        $TEMPLATES{$key} = $text
    }
    return \%TEMPLATES;
}
sub _build {
    my $self = shift;
    my(@rollback, $e);
    $self->_make('clean');
    eval {
        $self->_update_version_info;
        $self->_generate_file_from_template('MANIFEST.SKIP');
        $self->_system(sprintf '%s %s > %s', 'perldoc -tT', $self->top_module, 'README');
        eval { $self->_system('rm ' .$self->name .'* 2>/dev/null') }; # don't care if this fail
        push @rollback, sub { rename 'Changes.old', 'Changes' };
        $self->_timestamp_to_changes;
        -e and $self->_git(add => $_) for qw/ Changes Makefile.PL README mypp.yml t /;
        $self->_git(add => $self->top_module);
        push @rollback, sub { $self->_git(reset => 'HEAD^') };
        $self->_git(commit => -a => -m => $self->_changes_to_commit_message);
        push @rollback, sub { $self->_git(tag => -d => $self->changes->{version}) };
        $self->_git(tag => $self->changes->{version});
        $self->_make('manifest');
        $self->_make('dist');
        1;
    } or do {
        $e = $@ || 'Not sure what went wrong';
        eval { $_->() for reverse @rollback };
        warn "ROLLBACK FAILED: $@" if $@;
        die $e;
    };
}
sub _changes_to_commit_message {
    my $self = shift;
    my $text = $self->changes->{text};
    my $version = $self->changes->{version};
    # need to add extra line
    $text =~ s/.*\n/Released version $version\n\n/;
    $text;
}
sub _timestamp_to_changes {
    my $self = shift;
    my $date = localtime;
    my($changes, $pm);
    rename 'Changes', 'Changes.old' or die $!;
    open my $OLD, '<', 'Changes.old' or die "Read Changes.old: $!\n";
    open my $NEW, '>', 'Changes' or die "Write Changes: $!\n";
    { local $/; $changes = <$OLD> };
    if($changes =~ s/\n($VERSION_RE)\s*$/{ sprintf "\n%-7s  %s", $1, $date }/em) {
        print $NEW $changes;
        delete $self->{changes}; # need to re-read changes
        $self->_log("Add timestamp '$date' to Changes");
        return 1;
    }
    die "Unable to update Changes with timestamp\n";
}
sub _update_version_info {
  my $self = shift;
  my $top_module = $self->top_module;
  my $version = $self->changes->{version};
  my $top_module_text;
  {
    open my $MODULE, '<', $top_module or die "Read $top_module: $!\n";
    local $/;
    $top_module_text = <$MODULE>;
    $top_module_text =~ s/=head1 VERSION.*?\n=/=head1 VERSION\n\n$version\n\n=/s;
    $top_module_text =~ s/^((?:our)?\s*\$VERSION)\s*=.*$/$1 = '$version';/m;
  }
  {
    open my $MODULE, '>', $top_module or die "Write $top_module: $!\n";
    print $MODULE $top_module_text;
  }
  $self->_log("Update version in $top_module to $version");
  return 1;
}
sub _project_requires {
  my($self, $what) = @_;
  my(%run, %build, @run, @build, $corelist);
  my $wanted;
  if($self->{"requires_$what"}) {
    return $self->{"requires_$what"};
  }
  $wanted = sub {
    return if !-f $_;
    return if /\.swp/ ;
    open my $REQ, '-|', "$^X -MApp::Mypp::ShowINC -c '$_' 2>/dev/null";
    while(<$REQ>) {
      chomp;
      my($m, $v) = split /=/;
      $_[0]->{$m} = $v unless $run{$m};
    }
  };
  # required to skip core modules
  eval "use Module::CoreList; 1" and $corelist = 1;
  finddepth({ no_chdir => 1, wanted => sub { $wanted->(\%run) } }, 'bin') if -d 'bin';
  finddepth({ no_chdir => 1, wanted => sub { $wanted->(\%run) } }, 'lib');
  finddepth({ no_chdir => 1, wanted => sub { $wanted->(\%build) } }, 't');
  for my $m (sort keys %run) {
    my $v = $run{$m} || '0';
    next if $self->_got_parent_module($m, \%run);
    next if $corelist and Module::CoreList->first_release($m);
    push @run, "    '$m' => '$v',\n";
  }
  for my $m (sort keys %build) {
    my $v = $build{$m} || '0';
    next if $self->_got_parent_module($m, \%run);
    next if $corelist and Module::CoreList->first_release($m);
    push @build, "    '$m' => '$v',\n";
  }
  local $" = '';
  $self->{"requires_run"} = "@run";
  $self->{"requires_build"} = "@build";
  $self->{"requires_$what"};
}
sub _got_parent_module {
    my($self, $module, $map) = @_;
    for my $m (keys %$map) {
        next unless($map->{$m});
        next unless($module =~ /^$m\::/);
        next unless(!$map->{$module} or $map->{$module} eq $map->{$m});
        return 1;
    }
    return;
}
sub _share_via_extension {
    my $self = shift;
    my $file = $self->dist_file;
    my $share_extension = $self->share_extension;
    eval "use $share_extension; 1" or die "This feature requires $share_extension to be installed";
    # might die...
    if($share_extension eq 'CPAN::Uploader') {
        $share_extension->upload_file($file, {
            user => $self->pause_info->{user},
            password => $self->pause_info->{password},
        });
    }
    else {
        $share_extension->upload_file($file, @{ $self->share_params || [] });
    }
    return 1;
}
sub _generate_file_from_template {
    my($self, $file) = @_;
    my($content, $eval);
    if(-e $file and !$self->force) {
        $self->_log("$file already exists. (Skipping)");
        return;
    }
    $content = $self->_templates->{$file} or die "No such template defined: $file";
    $content =~ s!<%= ([^%]+) %>!{ local $_ = eval($1); warn "$1 => $@" if $@; chomp; $_ }!ge;
    mkdir dirname $file;
    $self->_write($file, $content);
    $self->_log("$file was generated");
}
sub _write {
  my($self, $file, @data) = @_;
  open my $FH, '>', $file or die "Write $file: $!";
  print $FH @data;
}
sub _system {
    local $_;
    shift->_log("\$ @_");
    open STDERR, '>', '/dev/null' if $SILENT;
    open STDOUT, '>', '/dev/null' if $SILENT;
    system @_; $_ = $?;
    open STDERR, '>&', $OLDERR if $SILENT;
    open STDOUT, '>&', $OLDOUT if $SILENT;
    die "system(@_) == $_" if $_;
    return 1;
}
sub _git {
    shift->_system(git => @_);
}
sub _make {
    my $self = shift;
    $self->_generate_file_from_template('Makefile.PL');
    $self->_system(perl => 'Makefile.PL') unless(-e 'Makefile');
    $self->_system(make => @_);
    return 1;
}
sub _log {
    return if $SILENT;
    print $_[1], "\n";
}
1;
}
__DATA__
%% t/00-basic.t =============================================================
use Test::More;
use File::Find;
if(($ENV{HARNESS_PERL_SWITCHES} || '') =~ /Devel::Cover/) {
  plan skip_all => 'HARNESS_PERL_SWITCHES =~ /Devel::Cover/';
}
if(!eval 'use Test::Pod; 1') {
  *Test::Pod::pod_file_ok = sub { SKIP: { skip "pod_file_ok(@_) (Test::Pod is required)", 1 } };
}
if(!eval 'use Test::Pod::Coverage; 1') {
  *Test::Pod::Coverage::pod_coverage_ok = sub { SKIP: { skip "pod_coverage_ok(@_) (Test::Pod::Coverage is required)", 1 } };
}
find(
  {
    wanted => sub { /\.pm$/ and push @files, $File::Find::name },
    no_chdir => 1
  },
  -e 'blib' ? 'blib' : 'lib',
);
plan tests => @files * 3;
for my $file (@files) {
  my $module = $file; $module =~ s,\.pm$,,; $module =~ s,.*/?lib/,,; $module =~ s,/,::,g;
  ok eval "use $module; 1", "use $module" or diag $@;
  Test::Pod::pod_file_ok($file);
  Test::Pod::Coverage::pod_coverage_ok($module);
}
%% MANIFEST.SKIP ============================================================
^mypp.yml
.git
\.old
\.swp
~$
^blib/
^Makefile$
^MANIFEST.*
^<%= $self->name %>
%% .gitignore ===============================================================
/META.yml
/MYMETA.*
/blib/
/inc/
/pm_to_blib
/MANIFEST
/MANIFEST.bak
/Makefile
/Makefile.old
*.old
*.swp
~$
/<%= $self->name %>*tar.gz
%% Changes ==================================================================
Revision history for <%= $self->name %>
0.01
       * Started project
       * Add cool feature
%% Makefile.PL ==============================================================
use ExtUtils::MakeMaker;
WriteMakefile(
  NAME => '<%= $self->top_module_name %>',
  ABSTRACT_FROM => '<%= $self->top_module %>',
  VERSION_FROM => '<%= $self->top_module %>',
  AUTHOR => '<%= qx{git config --get user.name} %> <<%= qx{git config --get user.email} %>>',
  LICENSE => 'perl',
  PREREQ_PM => {
<%= $self->_project_requires('run') %>
  },
  BUILD_REQUIRES => {
<%= $self->_project_requires('build') %>
  },
  META_MERGE => {
    resources => {
      license => 'http://dev.perl.org/licenses/',
      homepage => 'https://metacpan.org/release/<%= $self->name %>',
      bugtracker => '<%= $self->repository %>/issues',
      repository => '<%= $self->repository %>.git',
    },
  },
  test => {
    TESTS => 't/*.t',
  },
  #MIN_PERL_VERSION => 5.10,
  #EXE_FILES => ['bin/my-app'],
);
