package Dist::Zilla::PluginBundle::Author::IOANR 1.173490;

# ABSTRACT: Build dists the way IOANR likes

use v5.24;
use Moose;
use List::Util 1.33 'any';
use Dist::Zilla::Plugin::AssertOS;
use Dist::Zilla::Plugin::ChangelogFromGit::CPAN::Changes 0.173421;
use Dist::Zilla::Plugin::ContributorsFile;
use Dist::Zilla::Plugin::CopyFilesFromBuild;
use Dist::Zilla::Plugin::Git;
use Dist::Zilla::Plugin::Git::Contributors;
use Dist::Zilla::Plugin::GitHub;
use Dist::Zilla::Plugin::MetaData::BuiltWith;
use Dist::Zilla::Plugin::ModuleBuildTiny;
use Dist::Zilla::Plugin::MojibakeTests;
use Dist::Zilla::Plugin::PodWeaver 4.000;
use Dist::Zilla::Plugin::Prereqs::AuthorDeps;
use Dist::Zilla::Plugin::ReadmeAnyFromPod;
use Dist::Zilla::Plugin::RunExtraTests;
use Dist::Zilla::Plugin::Signature;
use Dist::Zilla::Plugin::Test::CheckDeps;
use Dist::Zilla::Plugin::Test::Compile;
use Dist::Zilla::Plugin::Test::EOL;
use Dist::Zilla::Plugin::Test::Kwalitee;
use Dist::Zilla::Plugin::Test::NoTabs;
use Dist::Zilla::Plugin::Test::Pod::No404s;
use Dist::Zilla::Plugin::Test::Portability;
use Dist::Zilla::Plugin::Test::ReportPrereqs;
use Dist::Zilla::Plugin::Test::Synopsis;
use Dist::Zilla::Plugin::Test::UnusedVars;
use Dist::Zilla::Plugin::Test::Version;

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

# TODO optionally add OSPreqs
# TODO Test::MinimumVersion - plugin generated test only checks META.yml, which we don't have

# plugins required to make a release, not neccessarily
# ones that *do* DZR::Releaser
has release_plugins => (is => 'ro', lazy_build => 1);

has autogenerated_files => (
    is      => 'ro',
    lazy    => 1,
    default => sub { [qw/README.md Changes LICENSE/] });

has allow_dirty_files => (
    is      => 'ro',
    lazy    => 1,
    default => sub {
        [$_[0]->autogenerated_files->@*, 'dist.ini',];
    },
);

sub _build_release_plugins {
    my $self = shift;

    my @release_plugins = (qw/TestRelease/);

    # do not allow any release to be made without the git plugins
    if ($ENV{DZIL_NO_GIT_LOCAL}) {
        return [@release_plugins, 'FakeRelease'];
    }

    # nothing further should happen without confirmation
    push @release_plugins, 'ConfirmRelease';

    # add plugins which make LOCAL REPO ONLY changes to git
    push @release_plugins,
      ['Git::Commit' => {allow_dirty => $self->allow_dirty_files}],
      [
        'Git::CommitBuild' => {
            branch               => '',
            release_branch       => 'release',
            release_message      => 'Release %v',
            multiple_inheritance => 1,
        }
      ],
      ['Git::Tag' => {signed => 1, branch => 'release'}];

    # add plugins which affect remote git remotes
    unless ($ENV{DZIL_NO_GIT_REMOTE}) {
        push @release_plugins, 'Git::Push',
          ['GitHub::Update' => {metacpan => 1}];
    }

    # DO NOT allow making a release to CPAN that isn't also pushed to remote git
    # DO allow making remote git changes without a CPAN release as it's easy to undo
    # and is useful for testing plugin settings
    if (($self->payload->{fake_release} || $ENV{DZIL_FAKE_RELEASE})
        || $ENV{DZIL_NO_GIT_REMOTE})
    {
        push @release_plugins, 'FakeRelease';
    } else {
        push @release_plugins, 'UploadToCPAN';
    }

    return \@release_plugins;
}

has build_plugin => (
    is      => 'ro',
    lazy    => 1,
    default => sub {
        if ($_[0]->payload->{custom_builder}) {
            return [ModuleBuild => {mb_class => 'My::Builder'}];
        } else {

            # TODO add an option to handle experimental statis installs
            # https://metacpan.org/pod/Dist::Zilla::Plugin::ModuleBuildTiny#static
            return 'ModuleBuildTiny';
        }
    });

sub mvp_multivalue_args {qw/disable assert_os/}

sub configure {
    my ($self) = @_;
    my $arg = $self->payload;

    my $change_opts = {
        exclude_message => '^(dist.ini|v(\d+\.?)+)',
        edit_changelog  => 1,
    };

    if ($arg->{semantic_version}) {
        $change_opts->{tag_regexp} = 'semantic';
    }

    if ($ENV{V}) {
        $self->add_plugins([AutoVersion => {format => q<{{ $ENV{V} }}>}]);
    } else {
        my $major = $arg->{major_version} || 0;
        $self->add_plugins([AutoVersion => {major => $major}]);
    }

    my @plugins = (
        'AutoPrereqs',
        ['ChangelogFromGit::CPAN::Changes' => $change_opts],
        'ContributorsFile',
        ['Git::Contributors'  => {order_by => 'commits'}],
        ['CopyFilesFromBuild' => {copy     => $self->autogenerated_files}],
        'ExecDir',
        [
            'Git::Check' => {
                allow_dirty     => $self->allow_dirty_files,
                build_warnings  => 1,
                untracked_files => 'warn',
            }
        ],
        [
            'Git::GatherDir' => {
                include_dotfiles => 1,
                exclude_filename => $self->autogenerated_files,
            }
        ],
        ['GitHub::Meta' => {homepage => 0}],
        'License',
        'Manifest',
        ['MetaData::BuiltWith' => {show_config => 1}],
        'MetaJSON',
        ['PodWeaver'  => {config_plugin => '@Author::IOANR'}],
        ['PkgVersion' => {use_package   => 1}],
        'Prereqs::AuthorDeps',
        'PruneCruft',
        ['ReadmeAnyFromPod' => {type => 'gfm', location => 'build'}],
        'ShareDir',
        'Signature',
        'MojibakeTests',
        'AuthorSignatureTest',
        'Test::CheckDeps',
        'Test::Compile',
        'Test::EOL',
        ['Test::Kwalitee' => {skiptest => [qw/has_readme/]}],
        'Test::NoTabs',
        'Test::Pod::No404s',
        'Test::Portability',
        'Test::ReportPrereqs',
        'Test::UnusedVars',
        'Test::Synopsis',
        'Test::Version',
    );

    # Test::Perl::Critic
    # PodCoverageTests
    # PodSyntaxTests

    push @plugins, $self->release_plugins->@*;
    my @add;
    while (my $p = shift @plugins) {
        next if any { $_ eq $p } $arg->{disable}->@*;
        push @add, $p;
    }

    push @add, $self->build_plugin;

    # these have to come after the builder
    push @add, 'RunExtraTests';

    if (exists $arg->{assert_os}) {
        push @add, [AssertOS => $self->config_slice({assert_os => 'os'})];
    }

    $self->add_plugins(@add);

    return;
}

__PACKAGE__->meta->make_immutable;
1;

__END__

=pod

=encoding UTF-8

=for :stopwords Ioan Rogers cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee
diff irc mailto metadata placeholders metacpan

=head1 NAME

Dist::Zilla::PluginBundle::Author::IOANR - Build dists the way IOANR likes

=head1 VERSION

version 1.173490

=head1 OPTIONS

=head2 C<fake_release>

Doesn't commit or release anything

  fake_release = 1

=head2 C<disable>

Specify plugins to disable. Can be specified multiple times.

  disable = Some::Plugin
  disable = Another::Plugin

=head2 C<assert_os>

Use L<Devel::AssertOS> to control which platforms this dist will build on.
Can be specified multiple times.

  assert_os = Linux

=head2 C<custom_builder>

If C<custom_builder> is set, L<Module::Build> will be used instead of
L<Module::Build::Tiny> with a custom build class set to C<My::Builder>

=head2 C<semantic_version>

If C<semantic_version> is true (the default), git tags will be in the form
C<^v(\d+\.\d+\.\d+)$>. Otherwise they will be C<^v(\d+\.\d+)$>.

=head1 SUPPORT

=head2 Perldoc

You can find documentation for this module with the perldoc command.

  perldoc Dist::Zilla::PluginBundle::Author::IOANR

=head2 Websites

The following websites have more information about this module, and may be of help to you. As always,
in addition to those websites please use your favorite search engine to discover more resources.

=over 4

=item *

MetaCPAN

A modern, open-source CPAN search engine, useful to view POD in HTML format.

L<https://metacpan.org/release/Dist-Zilla-PluginBundle-Author-IOANR>

=back

=head2 Bugs / Feature Requests

Please report any bugs or feature requests through the web interface at L<https://github.com/ioanrogers/Dist-Zilla-PluginBundle-Author-IOANR/issues>.
You will be automatically notified of any progress on the request by the system.

=head2 Source Code

The source code is available for from the following locations:

L<https://github.com/ioanrogers/Dist-Zilla-PluginBundle-Author-IOANR>

  git clone git://github.com/ioanrogers/Dist-Zilla-PluginBundle-Author-IOANR.git

=head1 AUTHOR

Ioan Rogers <ioanr@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2017 by Ioan Rogers.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
