Dist-Zilla-Plugin-DynamicPrereqs

 view release on metacpan or  search on metacpan

lib/Dist/Zilla/Plugin/DynamicPrereqs.pm  view on Meta::CPAN

            } map $_->basename, path($self->_include_sub_root)->children;

        [ sort($self->_all_required_subs_for(uniq(
            $self->include_subs, @subs_in_code,
        ))) ];
    },
);

my %required_subs;
sub _all_required_subs_for {
    my ($self, @subs) = @_;

    @required_subs{@subs} = (() x @subs);

    foreach my $sub (@subs) {
        my @subs = @{ $sub_dependencies{$sub} || [] };
        $self->_all_required_subs_for(@subs)
            if notall { exists $required_subs{$_} } @subs;
    }

    return keys %required_subs;
}

my %warn_include_sub = (
    can_xs => 1,
    can_cc => 1,
    can_run => 1,
);

sub _warn_include_subs {
    my ($self, @include_subs) = @_;

    $self->log(colored('Use ' . $_ . ' with great care! Please consult the documentation!', 'bright_yellow'))
        foreach grep exists $warn_include_sub{$_}, @include_subs;
}

__PACKAGE__->meta->make_immutable;

__END__

=pod

=encoding UTF-8

=head1 NAME

Dist::Zilla::Plugin::DynamicPrereqs - Specify dynamic (user-side) prerequisites for your distribution

=head1 VERSION

version 0.040

=head1 SYNOPSIS

In your F<dist.ini>:

    [DynamicPrereqs]
    -condition = has_module('Role::Tiny')
    -condition = !want_pp()
    -condition = can_xs()
    -body = requires('Role::Tiny', '1.003000')

or:

    [DynamicPrereqs]
    -delimiter = |
    -raw = |test_requires('Devel::Cover')
    -raw = |    if $ENV{EXTENDED_TESTING} or is_smoker();

or:

    [DynamicPrereqs]
    -raw_from_file = Makefile.args      # code snippet in this file

=head1 DESCRIPTION

This is a L<Dist::Zilla> plugin that inserts code into your F<Makefile.PL> to
indicate dynamic (installer-side) prerequisites.

Code is inserted immediately after the declarations for C<%WriteMakefileArgs>
and C<%FallbackPrereqs>, before they are conditionally modified (when an older
L<ExtUtils::MakeMaker> is installed).  This gives you an opportunity to add to
the C<WriteMakefile> arguments: C<PREREQ_PM>, C<BUILD_REQUIRES>, and
C<TEST_REQUIRES>, and therefore modify the prerequisites in the user's
F<MYMETA.yml> and F<MYMETA.json> based on conditions found on the user's system.

The C<dynamic_config> field in L<metadata|CPAN::Meta::Spec/dynamic_config> is
already set for you.

=for stopwords usecase

You could potentially use this plugin for performing other modifications in
F<Makefile.PL> other than user-side prerequisite modifications, but I can't
think of a situation where this makes sense. Contact me if you have any ideas!

Only F<Makefile.PL> modification is supported at this time. This author
considers the use of L<Module::Build> to be questionable in all circumstances,
and L<Module::Build::Tiny> does not (yet?) support dynamic configuration.

=head1 BE VIGILANT!

You are urged to check the generated F<Makefile.PL> for sanity, and to run it
at least once to validate its syntax. Although every effort is made to
generate valid and correct code, mistakes can happen, so verification is
needed before shipping.

Please also see the other warnings later in this document.

=head1 CONFIGURATION OPTIONS

=head2 C<-raw>

=head2 C<-body>

The code to be inserted; must be valid and complete perl statements. You can
reference and modify the already-declared C<%WriteMakefileArgs> and
C<%FallbackPrereqs> variables, as inserted into F<Makefile.PL> by
L<Dist::Zilla::Plugin::MakeMaker> and subclasses (e.g.
L<Dist::Zilla::Plugin::MakeMaker::Awesome> since L<Dist::Zilla> C<5.001>.

This option can be used more than once; lines are added in the order in which they are provided.

If you use external libraries in the code you are inserting, you B<must> add
these modules to C<configure_requires> prereqs in metadata (e.g. via
C<[Prereqs / ConfigureRequires]> in your F<dist.ini>).

C<-body> first became available in version 0.018.

=for Pod::Coverage mvp_multivalue_args mvp_aliases BUILD metadata after_build munge_files register_prereqs gather_files

=head2 C<-delimiter>

(Available since version 0.007)

A string, usually a single character, which is stripped from the beginning of
all C<-raw>/C<-body> lines. This is because the INI file format strips all leading
whitespace from option values, so including this character at the front allows
you to use leading whitespace in an option string, so you can indent blocks of
code properly.

=head2 C<-raw_from_file>

(Available since version 0.010)

=head2 C<-body_from_file>

(Available since version 0.018)

A filename that contains the code to be inserted; must be valid and complete
perl statements, as with C<-raw>/C<-body> above.  This file must be part of the build,
but it is pruned from the built distribution.

=head2 C<-condition>

(Available since version 0.014)

=for stopwords ANDed

A perl expression to be included in the condition statement in the
F<Makefile.PL>.  Multiple C<-condition>s can be provided, in which case they
are ANDed together to form the final condition statement. (You must
appropriately parenthesize each of your conditions to ensure correct order of
operations.)  Any use of recognized subroutines will cause their definitions
to be included automatically (see L<AVAILABLE SUBROUTINE DEFINITIONS>, below).

When combined with C<-raw>/C<-body> lines, the condition is placed first in a C<if>
statement, and the C<-raw>/C<-body> lines are contained as the body of the block. For example:

    [DynamicPrereqs]
    -condition = "$]" > '5.020'
    -body = requires('Role::Tiny', '1.003000')

results in the F<Makefile.PL> snippet (note that whitespace is not added, in
case this affects the parsing:

    if ("$]" > '5.020') {
    requires('Role::Tiny', '1.003000')
    }

=head2 C<-include_sub>

(Available since version 0.010; rendered unnecessary in 0.016 (all definitions
are now included automatically, when used).

=head1 AVAILABLE SUBROUTINE DEFINITIONS

A number of helper subroutines are available for use within your code inserted
via C<-body>, C<-body_from_file>, C<-raw>, C<-raw_from_file>, or C<-condition> clauses. When used, their
definition(s) will be included automatically in F<Makefile.PL> (as well as
those of any other subroutines I<they> call); necessary prerequisite modules
will be added to C<configure requires> metadata.

Unless otherwise noted, these all became available in version 0.010.
Available subs are:

=over 4

=item *

C<prompt_default_yes($message)> - takes a string (appending "[Y/n]" to it), returns a boolean; see L<ExtUtils::MakeMaker/prompt>

=item *

C<prompt_default_no($message)> - takes a string (appending "[y/N]" to it), returns a boolean; see L<ExtUtils::MakeMaker/prompt>

=item *

C<parse_args()> - returns the hashref of options that were passed as arguments to C<perl Makefile.PL>

=item *

C<can_xs()> - XS capability testing via L<ExtUtils::HasCompiler> (don't forget to also check C<want_pp>!) Available in this form since 0.029.

=item *

C<can_cc()> - can we locate a (the) C compiler

=item *

C<can_run()> - check if we can run some command

=item *

C<is_miniperl()> - returns true if the current perl is miniperl (this may affect your ability to run XS code) Available since 0.033.

=item *

C<can_use($module [, $version ])> - checks if a module (optionally, at a specified version) can be loaded. (If you don't want to load the module, you should use C<< has_module >>, see below.)

=for stopwords backcompat



( run in 2.416 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )