#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#   file: lib/Dist/Zilla/PluginBundle/Author/VDB.pm

#pod =encoding UTF-8
#pod
#pod =head1 COPYRIGHT AND LICENSE
#pod
#pod Copyright © 2015 Van de Bugger
#pod
#pod This file is part of perl-Dist-Zilla-PluginBundle-Author-VDB.
#pod
#pod perl-Dist-Zilla-PluginBundle-Author-VDB is free software: you can redistribute it and/or modify
#pod it under the terms of the GNU General Public License as published by the Free Software
#pod Foundation, either version 3 of the License, or (at your option) any later version.
#pod
#pod perl-Dist-Zilla-PluginBundle-Author-VDB is distributed in the hope that it will be useful, but
#pod WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
#pod PARTICULAR PURPOSE. See the GNU General Public License for more details.
#pod
#pod You should have received a copy of the GNU General Public License along with
#pod perl-Dist-Zilla-PluginBundle-Author-VDB. If not, see <http://www.gnu.org/licenses/>.
#pod
#pod =cut

#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#pod =head1 DESCRIPTION
#pod
#pod It is unlikely that someone else will want to use it, so I will not bother with documenting it, at
#pod least for now.
#pod
#pod =for Pod::Coverage configure
#pod
#pod =cut

package Dist::Zilla::PluginBundle::Author::VDB;

use Moose;
use namespace::autoclean;

# PODNAME: Dist::Zilla::PluginBundle::Author::VDB
# ABSTRACT: VDB's plugin bundle
our $VERSION = '0.006'; # VERSION

with 'Dist::Zilla::Role::PluginBundle::Easy';

use Carp qw{ croak };

#   Require all the modules explicitly now to avoid unexpected failures in the middle of release.
use IPC::System::Simple ();
use Path::Tiny 0.070;   ();
use Perl::Version       ();
use File::chdir         ();

#   Explicitly require all the plugins to let them appear in the metadata.
use Dist::Zilla::Plugin::AutoPrereqs                        ();
use Dist::Zilla::Plugin::CheckChangesHasContent             ();
use Dist::Zilla::Plugin::CheckExtraTests                    ();
use Dist::Zilla::Plugin::CheckPrereqsIndexed                ();
use Dist::Zilla::Plugin::ConfirmRelease                     ();
use Dist::Zilla::Plugin::FakeRelease                        ();
use Dist::Zilla::Plugin::GatherFromManifest                 ();
use Dist::Zilla::Plugin::Hook                       0.007   ();   # We need Hook::Releaser.
use Dist::Zilla::Plugin::Manifest::Write                    ();
use Dist::Zilla::Plugin::MetaJSON                           ();
use Dist::Zilla::Plugin::MetaProvides::Package              ();
use Dist::Zilla::Plugin::MetaResources::Template            ();
use Dist::Zilla::Plugin::MetaTests                          ();
use Dist::Zilla::Plugin::MetaYAML                           ();
use Dist::Zilla::Plugin::MinimumPerl                        ();
use Dist::Zilla::Plugin::ModuleBuildTiny                    ();
use Dist::Zilla::Plugin::MojibakeTests                      ();
use Dist::Zilla::Plugin::NextRelease                        ();
use Dist::Zilla::Plugin::OurPkgVersion                      ();
use Dist::Zilla::Plugin::PodCoverageTests                   ();
use Dist::Zilla::Plugin::PodSyntaxTests                     ();
use Dist::Zilla::Plugin::Prereqs::AuthorDeps                ();
use Dist::Zilla::Plugin::SurgicalPodWeaver                  ();
use Dist::Zilla::Plugin::Templates                          ();
use Dist::Zilla::Plugin::Test::Compile                      ();
use Dist::Zilla::Plugin::Test::CPAN::Changes                ();
use Dist::Zilla::Plugin::Test::CPAN::Meta::JSON             ();
use Dist::Zilla::Plugin::Test::DistManifest                 ();
use Dist::Zilla::Plugin::Test::EOL                          ();
use Dist::Zilla::Plugin::Test::Kwalitee                     ();
use Dist::Zilla::Plugin::Test::MinimumVersion               ();
use Dist::Zilla::Plugin::Test::NewVersion                   ();
use Dist::Zilla::Plugin::Test::NoTabs                       ();
use Dist::Zilla::Plugin::Test::Perl::Critic                 ();
use Dist::Zilla::Plugin::Test::Pod::No404s                  ();
use Dist::Zilla::Plugin::Test::PodSpelling                  ();
use Dist::Zilla::Plugin::TestRelease                        ();
use Dist::Zilla::Plugin::Test::Version                      ();
use Dist::Zilla::Plugin::UploadToCPAN                       ();

#   One more implicitly required module.
use Pod::Weaver::PluginBundle::Author::VDB                  ();

#pod =option minimum_perl
#pod
#pod C<Str>, optional, default value 5.006.
#pod
#pod =cut

has minimum_perl => (
    is          => 'ro',
    isa         => 'Str',
    lazy        => 1,
    default     => sub {
        my ( $self ) = @_;
        return $self->payload->{ minimum_perl } // '5.006';
    },
);

#pod =option fake_release
#pod
#pod If true (C<1>), release will be a fake one, i. e. no external operations will be done:
#pod C<UploadToCPAN> plugin will be replaced with C<FakeRelease> (which does nothing), and C<hg push>
#pod will not be performed.
#pod
#pod Option can be set trough F<dist.ini> file or with C<FAKE_RELEASE> environment variable.
#pod
#pod C<Bool>, optional, default value is 0.
#pod
#pod =cut

has fake_release => (
    is          => 'ro',
    isa         => 'Bool',
    lazy        => 1,
    default     => sub {
        my ( $self ) = @_;
        return $self->payload->{ fake_release } // $ENV{ FAKE_RELEASE };
    },
);

#pod =option archive
#pod
#pod Directory to archive files to. If empty, release will not be archived. If such directory does not
#pod exist, it will be created before release.
#pod
#pod C<Str>, optional, default value ".releases".
#pod
#pod =cut

has archive => (
    is          => 'ro',
    isa         => 'Str',
    lazy        => 1,
    default     => sub {
        my ( $self ) = @_;
        return $self->payload->{ archive } // '.releases';
    },
);

#pod =option templates
#pod
#pod This option will be passed to C<Templates> plugin. If you no not want C<Templates> to process
#pod files, specify C<:NoFiles>. This is multi-value option (i. e. may be specified several times).
#pod
#pod C<ArrayRef[Str]>, optional, default value C<[ ':InstallModules' ]>.
#pod
#pod =cut

has templates => (
    is          => 'ro',
    isa         => 'ArrayRef[Str]',
    lazy        => 1,
    default     => sub {
        my ( $self ) = @_;
        return $self->payload->{ templates } // [ ':InstallModules' ];
    },
);

#pod =option unwanted_module
#pod
#pod TODO
#pod
#pod =cut

has unwanted_modules => (
    is          => 'ro',
    isa         => 'Str',
    lazy        => 1,
    default     => sub {
        my ( $self ) = @_;
        my $p  = $self->payload;
        my $u1 = $p->{ unwanted_module  };
        my $u2 = $p->{ unwanted_modules };
        my $u;
        if ( $u1 or $u2 ) {
            $u = join( ' ', $u1 ? @$u1 : (), $u2 ? @$u2 : () );
        } else {
            $u = 'DDP Data::Printer';
        };
        if ( $u =~ m{[{,}]}x ) {
            croak "oops";
        };
        return "qw{ $u }";
    },
);

#pod =method mvp_multivalue_args
#pod
#pod =cut

sub mvp_multivalue_args {
    return qw{ templates unwanted_module unwanted_modules };
};

sub configure {

    my ( $self ) = @_;

    $self->add_plugins(

        [ 'Hook' => 'prologue' => {
            # DOES NOT WORK because plugin name will be '@Author::VDB/prologue'.
            'hook' => [ q{
                use autodie ':all';
                use IPC::System::Simple qw{ capture };
                use Path::Tiny;
            } ],
        } ],

        [ 'Hook::VersionProvider' => {
            'hook' => [ q{
                use Path::Tiny;
                my $file = path( 'VERSION' );
                my $version = $file->slurp =~ s{\s+\z}{}r;
                if ( $version !~ m{\A@{ [ Perl::Version::REGEX ] }\z} ) {
                    $self->abort( [
                        'Invalid version string "%s" at %s line 1', $version, "$file"
                    ] );
                };
                $version;
            } ],
        } ],

        [ 'Hook::Init' => 'my vars' => {
            'hook' => [ q{
                pack} . q{age MY {          # Hide declaration from `new-version.t`.
                    our $name           = $dist->name;
                    our $package        = $name =~ s{-}{::}gr;
                    our $version        = $dist->version;
                    our $Abstract       = $dist->abstract;
                    our $abstract       = lcfirst( $Abstract );
                    our $author         = $dist->authors->[ -1 ];
                    our $metacpan       = "https://metacpan.org/release/$name";
                    our $cpan_rt_mailto = "mailto:bug-$name\@rt.cpan.org";
                    our $cpan_rt_browse = "https://rt.cpan.org/Public/Dist/Display.html?Name=$name";
                    our $cpan_rt_report = "https://rt.cpan.org/Public/Bug/Report.html?Queue=$name";
                    our $repo_type      = "hg";
                    our $repo_host      = "fedorapeople.org";
                    our $repo_url       = "https://vandebugger.$repo_host/hg/perl-$name";
                    our $repo_web       = undef;
                    our $repo_clone     = "$repo_type clone $repo_url" .
                        ( $repo_url =~ m{/\Qperl-$name\E\z} ? '' : " \\\n        perl-$name" );
                };
                $ENV{ 'TEST_FIX' . 'ME_FORMAT' } = 'perl';      # Hide keyword from `fixme.t`.
            } ],
        } ],

        #
        #   Files to include
        #

        [ 'GatherFromManifest' ],

        #
        #   Generated files
        #

        [ 'Manifest::Write' => {
            'source_providers' => [
                'GatherFromManifest',
                'GenerateFile',
            ],
        } ],

        #
        #   File mungers
        #

        [ 'OurPkgVersion' ],

        [ 'SurgicalPodWeaver' => {
            'config_plugin' => '@Author::VDB',
            'replacer'      => 'replace_with_comment',
        } ],

        [ 'FileFinder::ByName' => 'source doc' => {
            # Plugin name will be `@Author::VDB/doc`.
            'file' => [
                'COPYING',
                'README',
            ],
        } ],

        [ 'Templates' => {
            'templates' => [
                '@Author::VDB/source doc',
                @{ $self->templates },
            ],
        } ],

        #
        #   Update sources
        #

        #   Copy built doc files back to source directory.
        [ 'Hook::AfterBuild' => {
            'hook' => [ q{
                use Path::Tiny;
                my $files = $zilla->plugin_named( '@Author::VDB/source doc' )->find_files();
                my $build = path( $arg->{ build_root } );
                my $root  = path( $dist->root );
                for my $file ( @$files ) {
                    my $new_file = $build->child( $file->name );
                    my $old_file = $root->child( $file->name );
                    my $new_bulk = $new_file->slurp;
                    my $old_bulk = $old_file->exists ? $old_file->slurp : undef;
                    if ( not defined( $old_bulk ) or $new_bulk ne $old_bulk ) {
                        $self->log( [ 'Updating %s...', $file->name ] );
                        $old_file->spew( $new_bulk );
                    };
                };
            } ],
        } ],

        #
        #   Tests
        #

        # Files

        [ 'Test::EOL' => {
            'finder' => ':AllFiles',
        } ],

        [ 'Test::NoTabs' => {
            'finder' => ':AllFiles',
        } ],

        [ 'MojibakeTests' ],

        # Code

        [ 'Test::Compile' => {
            'fake_home' => 1,
        } ],

        [ 'Test::Version' => {          # All modules have version.
            #~ 'is_strict' => 1,        # Does not work for trial releases.
        } ],

        [ 'Test::NewVersion' ],         # This is not a version already uploaded to CPAN.
        [ 'Test::MinimumVersion' => {
            'max_target_perl' => $self->minimum_perl,
        } ],

        [ 'Test::Fix' . 'me' ],

        [ 'Test::Perl::Critic' => {
            'critic_config' => 'xt/perlcritic.ini',
                #   The test does not check tests. TODO: How to fix?
        } ],

        # POD

        [ 'PodSyntaxTests'   ],     # `Dist-Zilla`-bundled test, uses `Test::pod`.

        [ 'PodCoverageTests' ],     # `Dist-Zilla`-bundled test, uses `Pod::Coverage::TrustPod`.

        [ 'Test::PodSpelling' => {
            'spell_cmd' => 'aspell list -l en -p ./xt/aspell.en.pws',
                #   Leading dot (in `./xt/aspell.en.pws`) is important! Whitout the dot `aspell`
                #    fails to find the dictionary.
        } ],

        [ 'Test::Pod::No404s' ],    # No dead URLs.

        # Metadata

        [ 'MetaTests' ],    # `Dist-Zilla`-bundled test, uses `Test::CPAN::Meta`, checks `META.yml`.

        [ 'Test::CPAN::Meta::JSON' ],   # Uses `Test::CPAN::Meta::JSON`.

        [ 'Test::CPAN::Changes' ],
            #   Does not check that `Changes` has a record for current version, see
            #   <https://github.com/doherty/Dist-Zilla-Plugin-Test-CPAN-Changes/issues/6>.

        [ 'Test::DistManifest' ],

        # Overall

        [ 'Test::Kwalitee' ],

        #
        #   Metainfo
        #

        [ 'MinimumPerl' ],

        [ 'AutoPrereqs' ],

        #   `Prereqs::AuthorDeps` has a problem:
        #       <https://github.com/dagolden/Dist-Zilla-Plugin-Prereqs-AuthorDeps/issues/1>
        #   It adds local plugins (e. g. tools::GenerateHooks) to the dependencies,
        #   which obviously are not indexed on CPAN.
        [ 'Prereqs::AuthorDeps' => {
            #~ 'exclude' => [
                #~ #   Exclude option requires a list of specific files, while I want to ignore all
                #~ #   files in specific directory.
            #~ ],
        } ],

        #   TODO: Remove when possible.
        #   This is a dirty hack. Remove it when `Prereqs::AuthorDeps` allows me to ignore all the
        #   modules from `tools/` directory. Meanwhile, find and remove all the dependencies on
        #   modules with `tools::` prefix.
        [ 'Hook::PrereqSource' => 'tools' => {
            'hook' => [ q{
                my $prereqs = $dist->prereqs->cpan_meta_prereqs;
                for my $phase ( $prereqs->__legal_phases ) {
                for my $type  ( $prereqs->__legal_types  ) {
                    my $reqs = $prereqs->requirements_for( $phase, $type ) or next;
                    for my $module ( keys( %{ $reqs->{ requirements } } ) ) {
                        if ( $module =~ m{^tools::} ) {
                            $self->log_debug( [
                                'found dependency on module %s at phase %s of type %s, deleting it',
                                $module, $phase, $type
                            ] );
                            delete( $reqs->{ requirements }->{ $module } );
                        };
                    };
                };
                };
            } ],
        } ],

        #   `use autodie ':all';` implicitly requires `IPC::System::Simple` module, but this
        #   dependency is not detected by `AutoPrereqs`. If there is dependency on `autodie`, let
        #   us add dependency on `IPC::System::Simple`.
        [ 'Hook::PrereqSource' => 'autodie' => {
            'hook' => [ q{
                my $prereqs = $dist->prereqs->cpan_meta_prereqs;
                for my $phase ( $prereqs->__legal_phases ) {
                for my $type  ( $prereqs->__legal_types  ) {
                    my $reqs = $prereqs->requirements_for( $phase, $type ) or next;
                    for my $module ( keys( %{ $reqs->{ requirements } } ) ) {
                        if ( $module eq 'autodie' ) {
                            $self->log_debug( [
                                'found dependency on module %s at phase %s type %s, ' .
                                    'adding dependency on IPC::System::Simple',
                                $module, $phase, $type
                            ] );
                            $dist->register_prereqs(
                                { phase => $phase, type => $type },
                                'IPC::System::Simple' => 0,
                            );
                        };
                    };
                };
                };
            } ],
        } ],

        [ 'CheckPrereqsIndexed'   ],    # Make sure all prereqs are published in CPAN.

        [ 'MetaProvides::Package' ],

        [ 'MetaResources::Template' => {
            'delimiters'          => '{ }',
            'homepage'            => '{$MY::metacpan}',
            'license'             => '{$dist->license->url}',
            'repository.type'     => '{$MY::repo_type}',
            'repository.url'      => '{$MY::repo_url}',
            'repository.web'      => '{$MY::repo_web}',
            'bugtracker.mailto'   => '{$MY::cpan_rt_mailto}',
            'bugtracker.web'      => '{$MY::cpan_rt_browse}',
        } ],

        [ 'MetaYAML' ],                 # Generate `META.yml`.

        [ 'MetaJSON' ],                 # Generate `META.json`.

        #
        #   Installer
        #

        [ 'ModuleBuildTiny' ],

        #
        #   Release
        #

        $self->archive ? (
            #   Make sure archive directory exists. Do it in the very beginnig of release because
            #   it is simple and fast operation. It will be annoying to pass all the tests and
            #   stop release  because `dzil` fails to create archive directory.
            [ 'Hook::BeforeRelease' => 'archive directory' => {
                'hook' => [ q{
                    my $root = path( $self->zilla->root . '' );
                    my $dir = path( "} . $self->archive . q{" );
                    if ( $dir->is_absolute ) {
                        $self->log_error( [ 'Bad archive directory: %s', "$dir" ] );
                        $self->log_error( [ 'Absolute path not allowed.' ] );
                        $self->abort();
                    };
                    if ( not $dir->is_dir ) {
                        $self->log( [ 'Creating archive directory %s...', "$dir" ] );
                        $dir->mkpath();
                    };
                } ],
            } ]
        ) : (
        ),

        #~ [ 'RunExtraTests' ],         # Does not work for me, see <https://github.com/dagolden/Dist-Zilla-Plugin-CheckExtraTests/issues/26>.
        [ 'CheckExtraTests' ],          # So use CheckExtraTest meanwhile.

        [ 'TestRelease'     ],          # Unpack tarball and run tests.

        #   Make sure the distro does not depend on unwanted modules. Unwanted module, for example,
        #   is `Data::Printer`. I use it often for debugging purposes and forget to remove
        #   debugging code.
        [ 'Hook::BeforeRelease' => 'unwanted deps' => {
            'hook' => [ q{
                my @modules = } . $self->unwanted_modules . q{;
                my $prereqs = $dist->distmeta->{ prereqs };
                my $header;
                for my $module ( @modules ) {
                    for my $stage ( qw{ configure develop runtime test } ) {
                        if ( exists( $prereqs->{ $stage }->{ requires }->{ $module } ) ) {
                            if ( not $header ) {
                                $self->log_error( 'Unwanted modules found:' );
                                $header = 1;
                            };
                            $self->log_error( [ '    %s in %s prereqs ', $module, $stage ] );
                        };
                    };
                };
                $self->abort_if_error();
            } ]
        } ],

        [ 'CheckChangesHasContent' ],

        [ 'Hook::BeforeRelease' => 'hg check tag' => {
            'hook' => [ q{
                #   Make sure there is no such tag yet.
                use Path::Tiny;
                if ( path( '.hgtags' )->slurp_utf8 =~ m{ \Q$MY::version\E$}m ) {
                    $self->abort( [ 'tag %s already exists', $MY::version ] );
                };
            } ],
        } ],

        [ 'Hook::BeforeRelease' => 'hg stat' => {
            'hook' => [ q{
                #   Make sure all the files committed.
                use IPC::System::Simple 'capture';
                my @stdout = capture( 'hg', 'status' );
                if ( @stdout ) {
                    chomp( @stdout );
                    $self->log_error( 'hg status:' );
                    $self->log_error( "    $_" ) for @stdout;
                    $self->abort( 'hg status is not clean' );
                };
            } ],
        } ],

        [ 'ConfirmRelease' ],       # Ask confirmation before uploading the release.

        [ 'Hook::Releaser' => 'tgz' => {
            'hook' => [ q{
                $MY::tgz = $arg;
            } ],
        } ],

        #   `Archive` is a good plugin, but I want to copy, not move tarball, because I am going to
        #   install it later.
        $self->archive ? (
            [ 'Hook::Releaser' => 'archive release' => {
                'hook' => [ q{
                    use Path::Tiny;
                    my $tgz = path( $arg );
                    my $dir = path( "} . $self->archive . q{" );
                    $self->log( [ 'Copying %s to %s...', "$tgz", "$dir" ] );
                    $tgz->copy( $dir->child( $tgz->basename ) );
                } ],
            } ],
        ) : (
        ),

        $self->fake_release ? (
            [ 'FakeRelease' ],
        ) : (
            [ 'UploadToCPAN' ],
        ),

        [ 'Hook::AfterRelease' => 'hg add tag' => {
            'hook' => [ q{
                use IPC::System::Simple 'capture';
                my @stdout = capture( 'hg', 'id', '--debug' );
                chomp( @stdout );
                @stdout == 1 and $stdout[ 0 ] =~ m{^([0-9a-f]{40})(\+?) tip$} or do {
                    $self->log_error( 'fail to parse "hg id" output:' );
                    $self->log_error( "    $_" ) for @stdout;
                    $self->abort();
                };
                my ( $id, $dirty ) = ( $1, $2 );
                if ( $dirty ) {
                    $self->abort( 'hg status is not clean' );
                };
                path( '.hgtags' )->append( "$id $MY::version\n" );
            } ],
        } ],

        [ 'NextRelease' => {
            'format'      => '%V @ %{yyyy-MM-dd HH:mm zzz}d',
            'time_zone'   => 'UTC',
        } ],

        [ 'Hook::AfterRelease' => 'bump version' => {
            'hook' => [ q{
                use Path::Tiny;
                use Perl::Version;
                my $version = Perl::Version->new( $dist->version );
                $version->inc_alpha;
                path( 'VERSION' )->spew( $version );
                $self->log( [ 'Next release will be %s', "$version" ] );
            } ],
        } ],

        [ 'Hook::AfterRelease' => 'hg post-commit' => {
            'hook' => [ q{
                use autodie ':all';
                system(
                    'hg', 'commit', '-m', 'Post-release commit',
                        qw{ .hgtags VERSION Changes }
                );
            } ],
        } ],

        [ 'Hook::AfterRelease' => 'hg push' => {
            'hook' => [
                $self->fake_release ? ( q{
                    $self->log( 'Fake release, skipping "hg push"...' );
                } ) : ( q{
                    use IPC::System::Simple 'capture';
                    my @stdout = capture( 'hg', 'push' );
                    chomp( @stdout );
                    $self->log( "    $_" ) for @stdout;
                } ),
            ],
        } ],

        [ 'Hook::AfterRelease' => 'install' => {
            'hook' => [ q{
                use autodie ':all';
                use File::chdir;
                local $CWD = $zilla->built_in;
                system( 'cpanm', '--notest', '.' );
                    # ^ We run the tests on unpacked tarball before release, no need in running
                    #   tests one more time.
            } ],
        } ],

        [ 'Hook::AfterRelease' => 'clean' => {
            'hook' => [ q{
                $zilla->clean();
            } ],
        } ],

    );

    return;

};

__PACKAGE__->meta->make_immutable();

1;

# doc/what.pod #

#pod =encoding UTF-8
#pod
#pod =head1 WHAT?
#pod
#pod C<Dist-Zilla-PluginBundle-Author-VDB> (or just C<@Author::VDB>) is a C<Dist-Zilla> plugin bundle used by VDB.
#pod
#pod =cut

# end of file #
# doc/why.pod #

#pod =encoding UTF-8
#pod
#pod =head1 WHY?
#pod
#pod I have published few distributions on CPAN. Every distribution have F<dist.ini> file. All the
#pod F<dist.ini> files are very similar. Maintaining multiple very similar F<dist.ini> files is boring.
#pod Plugin bundle solves the problem.
#pod
#pod =cut

# end of file #


# end of file #

__END__

=pod

=encoding UTF-8

=head1 NAME

Dist::Zilla::PluginBundle::Author::VDB - VDB's plugin bundle

=head1 VERSION

Version 0.006, released on 2015-08-14 00:31 UTC.

=head1 WHAT?

C<Dist-Zilla-PluginBundle-Author-VDB> (or just C<@Author::VDB>) is a C<Dist-Zilla> plugin bundle used by VDB.

=head1 DESCRIPTION

It is unlikely that someone else will want to use it, so I will not bother with documenting it, at
least for now.

=head1 OBJECT METHODS

=head2 mvp_multivalue_args

=head1 OPTIONS

=head2 minimum_perl

C<Str>, optional, default value 5.006.

=head2 fake_release

If true (C<1>), release will be a fake one, i. e. no external operations will be done:
C<UploadToCPAN> plugin will be replaced with C<FakeRelease> (which does nothing), and C<hg push>
will not be performed.

Option can be set trough F<dist.ini> file or with C<FAKE_RELEASE> environment variable.

C<Bool>, optional, default value is 0.

=head2 archive

Directory to archive files to. If empty, release will not be archived. If such directory does not
exist, it will be created before release.

C<Str>, optional, default value ".releases".

=head2 templates

This option will be passed to C<Templates> plugin. If you no not want C<Templates> to process
files, specify C<:NoFiles>. This is multi-value option (i. e. may be specified several times).

C<ArrayRef[Str]>, optional, default value C<[ ':InstallModules' ]>.

=head2 unwanted_module

TODO

=head1 WHY?

I have published few distributions on CPAN. Every distribution have F<dist.ini> file. All the
F<dist.ini> files are very similar. Maintaining multiple very similar F<dist.ini> files is boring.
Plugin bundle solves the problem.

=for Pod::Coverage configure

=head1 AUTHOR

Van de Bugger <van.de.bugger@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright © 2015 Van de Bugger

This file is part of perl-Dist-Zilla-PluginBundle-Author-VDB.

perl-Dist-Zilla-PluginBundle-Author-VDB is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.

perl-Dist-Zilla-PluginBundle-Author-VDB is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
perl-Dist-Zilla-PluginBundle-Author-VDB. If not, see <http://www.gnu.org/licenses/>.

=cut
