Group
Extension

Dist-Zilla-Util-EmulatePhase/lib/Dist/Zilla/Util/EmulatePhase.pm

use 5.006;    # our
use strict;
use warnings;

package Dist::Zilla::Util::EmulatePhase;

our $VERSION = '1.001002';

#ABSTRACT: Nasty tools for probing Dist::Zilla's internal state.

our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY

use Scalar::Util qw( refaddr );
use Try::Tiny;
use Sub::Exporter -setup => {
  exports => [qw( deduplicate expand_modname get_plugins get_metadata get_prereqs)],
  groups  => [ default => [qw( -all )] ],
};





















sub deduplicate {
  my ( @args, ) = @_;
  my ( %seen, @out );
  for my $item (@args) {
    push @out, $item unless exists $seen{$item};
    $seen{$item} = 1;
  }
  return @out;
}










sub expand_modname {
  ## no critic ( RegularExpressions::RequireDotMatchAnything RegularExpressions::RequireExtendedFormatting RegularExpressions::RequireLineBoundaryMatching )
  my $v = shift;
  $v =~ s/^-/Dist::Zilla::Role::/;
  $v =~ s/^=/Dist::Zilla::Plugin::/;
  return $v;
}















sub get_plugins {
  my ($config) = @_;
  if ( not $config or not exists $config->{'zilla'} ) {
    require Carp;
    ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
    Carp::croak('get_plugins({ zilla => $something }) is a minimum requirement');
  }
  my $zilla = $config->{zilla};

  if ( not $zilla->isa('Dist::Zilla') ) {

    #require Carp;
    #Carp::cluck('get_plugins({ zilla => $something}) is not Dist::Zilla, might be a bug');
  }

  my $plugins = [];

  if ( $zilla->can('plugins') ) {
    $plugins = $zilla->plugins();
  }
  else {
    return;
  }

  if ( not @{$plugins} ) {
    return;
  }

  if ( exists $config->{'with'} ) {
    my $old_plugins = $plugins;
    $plugins = [];
    for my $with ( map { expand_modname($_) } @{ $config->{with} } ) {
      push @{$plugins}, grep { $_->does($with) } @{$old_plugins};
    }
  }

  if ( exists $config->{'skip_with'} ) {
    for my $value ( @{ $config->{'skip_with'} } ) {
      my $without = expand_modname($value);
      $plugins = [ grep { not $_->does($without) } @{$plugins} ];
    }
  }

  if ( exists $config->{'isa'} ) {
    my $old_plugins = $plugins;
    $plugins = [];
    for my $isa_package ( @{ $config->{isa} } ) {
      my $isa = expand_modname($isa_package);
      push @{$plugins}, grep { $_->isa($isa) } @{$old_plugins};
    }
  }

  if ( exists $config->{'skip_isa'} ) {
    for my $value ( @{ $config->{'skip_isa'} } ) {
      my $isnt = expand_modname($value);
      $plugins = [ grep { not $_->isa($isnt) } @{$plugins} ];
    }
  }

  return deduplicate( @{$plugins} );
}





















sub get_metadata {
  my ($config) = @_;
  if ( not $config or not exists $config->{'zilla'} ) {
    require Carp;
    ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
    Carp::croak('get_metadata({ zilla => $something }) is a minimum requirement');
  }
  $config->{with} = [] unless exists $config->{'with'};
  push @{ $config->{'with'} }, '-MetaProvider';
  my @plugins = get_plugins($config);
  my $meta    = {};
  for my $value (@plugins) {
    require Hash::Merge::Simple;
    $meta = Hash::Merge::Simple::merge( $meta, $value->metadata );
  }
  return $meta;
}





















sub get_prereqs {
  my ($config) = @_;
  if ( not $config or not exists $config->{'zilla'} ) {
    require Carp;
    ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
    Carp::croak('get_prereqs({ zilla => $something }) is a minimum requirement');
  }

  $config->{'with'} = [] unless exists $config->{'with'};
  push @{ $config->{'with'} }, '-PrereqSource';
  my @plugins = get_plugins($config);

  # This is a bit nasty, because prereqs call back into their data and mess with zilla :/
  require Dist::Zilla::Util::EmulatePhase::PrereqCollector;
  my $zilla = Dist::Zilla::Util::EmulatePhase::PrereqCollector->new( shadow_zilla => $config->{zilla} );
  for my $value (@plugins) {
    {    # subverting!
      ## no critic ( Variables::ProhibitLocalVars )
      local $value->{zilla} = $zilla;
      $value->register_prereqs;
    }
    if ( refaddr($zilla) eq refaddr( $value->{zilla} ) ) {
      require Carp;
      Carp::croak('Zilla did not reset itself');
    }
  }
  $zilla->prereqs->finalize;
  return $zilla->prereqs;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Dist::Zilla::Util::EmulatePhase - Nasty tools for probing Dist::Zilla's internal state.

=head1 VERSION

version 1.001002

=head1 METHODS

=head2 deduplicate

Internal utility that de-duplicates references by ref-addr alone.

  my $array = [];
  is_deeply( [ deduplicate( $array, $array ) ],[ $array ] )

=head2 expand_modname

Internal utility to expand various shorthand notations to full ones.

  expand_modname('-MetaProvider') == 'Dist::Zilla::Role::MetaProvider';
  expand_modname('=MetaNoIndex')  == 'Dist::Zilla::Plugin::MetaNoIndex';

=head2 get_plugins

Probe Dist::Zilla's plugin registry and get items matching a specification

  my @plugins = get_plugins({
    zilla     => $self->zilla,
    with      => [qw( -MetaProvider -SomethingElse     )],
    skip_with => [qw( -SomethingBadThatIsAMetaProvider )],
    isa       => [qw( =SomePlugin   =SomeOtherPlugin   )],
    skip_isa  => [qw( =OurPlugin                       )],
  });

=head2 get_metadata

Emulates Dist::Zilla's internal metadata aggregation and does it all again.

Minimum Usage:

  my $metadata = get_metadata({ zilla => $self->zilla });

Extended usage:

  my $metadata = get_metadata({
    $zilla = $self->zilla,
     ... more params to get_plugins ...
     ... ie: ...
     with => [qw( -MetaProvider )],
     isa  => [qw( =MetaNoIndex )],
   });

=head2 get_prereqs

Emulates Dist::Zilla's internal prereqs aggregation and does it all again.

Minimum Usage:

  my $prereqs = get_prereqs({ zilla => $self->zilla });

Extended usage:

  my $metadata = get_prereqs({
    $zilla = $self->zilla,
     ... more params to get_plugins ...
     ... ie: ...
     with => [qw( -PrereqSource )],
     isa  => [qw( =AutoPrereqs )],
   });

=begin MetaPOD::JSON v1.1.0

{
    "namespace":"Dist::Zilla::Util::EmulatePhase",
    "interface":"exporter"
}


=end MetaPOD::JSON

=head1 AUTHOR

Kent Fredric <kentnl@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Kent Fredric <kentnl@cpan.org>.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut


Powered by Groonga
Maintained by Kenichi Ishigaki <ishigaki@cpan.org>. If you find anything, submit it on GitHub.