Skip to content

Commit

Permalink
Add container = property for loading and routing beam containers
Browse files Browse the repository at this point in the history
  • Loading branch information
kentfredric committed Apr 13, 2016
1 parent f8e4cf8 commit ec28ca6
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 5 deletions.
6 changes: 5 additions & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ my %WriteMakefileArgs = (
"MIN_PERL_VERSION" => "5.006",
"NAME" => "Dist::Zilla::Plugin::Beam::Connector",
"PREREQ_PM" => {
"Beam::Wire" => 0,
"Carp" => 0,
"Dist::Zilla::Role::Plugin" => 0,
"Moose" => 0,
"MooseX::LazyRequire" => 0,
"Path::Tiny" => 0,
"strict" => 0,
"warnings" => 0
},
"TEST_REQUIRES" => {
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"Path::Tiny" => 0,
"Test::DZil" => 0,
"Test::More" => "0.89",
"constant" => 0,
Expand All @@ -40,11 +42,13 @@ my %WriteMakefileArgs = (


my %FallbackPrereqs = (
"Beam::Wire" => 0,
"Carp" => 0,
"Dist::Zilla::Role::Plugin" => 0,
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"Moose" => 0,
"MooseX::LazyRequire" => 0,
"Path::Tiny" => 0,
"Test::DZil" => 0,
"Test::More" => "0.89",
Expand Down
6 changes: 6 additions & 0 deletions README.mkdn
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ version 0.001000
; PluginA emitting event 'foo' passes the event to PluginB
on = plugin:PluginA#foo => plugin:PluginB#handle_foo
on = plugin:PluginA#bar => plugin:PluginB#handle_bar
; Load 'beam.yml' as a Beam::Wire container
container = beam.yml
; Handle Dist::Zilla plugin events with arbitrary classes
; loaded by Beam::Wire
on = plugin:PluginA#foo => container:servicename#handle_foo
on = plugin:PluginA#bar => container:otherservicename#handle_bar

# DESCRIPTION

Expand Down
9 changes: 9 additions & 0 deletions examples/neo-makemaker/beam.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
dyninject_g:
class: inc::My::NeoDynDepsLite
args:
letter: G
dyninject_m:
$class: inc::My::NeoDynDepsLite
letter: M

3 changes: 3 additions & 0 deletions examples/neo-makemaker/dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@ prune_directory = ^Example-
[=inc::My::NeoDynDeps / NDD]

[Beam::Connector]
container = beam.yml
on = plugin:MM#generate_prelude => plugin:NDD#inject_prelude
on = plugin:MM#generate_prelude => plugin:NDD#inject_prelude
on = plugin:MM#generate_prelude => container:dyninject_g#inject_prelude
on = plugin:MM#generate_prelude => container:dyninject_m#inject_prelude
28 changes: 28 additions & 0 deletions examples/neo-makemaker/inc/My/NeoDynDepsLite.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use 5.006;
use strict;
use warnings;

package inc::My::NeoDynDepsLite;

# ABSTRACT: A Lightweight injector thingy

# AUTHORITY

# Look ma, no Dzil! no Moose! Nothing!

sub new { return bless { ref $_[1] ? %{ $_[1] } : @_[ 1 .. $#_ ] }, $_[0] }

# This is obviously a rediculously tiny and simple big of code
# in comparison with the normal shenanigans.
sub inject_prelude {
my ( $self, $event ) = @_;
my $text = $event->prelude;
my $letter = $self->{letter} || 'H';
$text .= <<"EOF";
print "This message brought to you by the letter $letter";
EOF
$event->prelude($text);
return;
}

1;
45 changes: 41 additions & 4 deletions lib/Dist/Zilla/Plugin/Beam/Connector.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ our $VERSION = '0.001000';
# AUTHORITY

use Moose qw( has around with );
use MooseX::LazyRequire;
use Carp qw( croak );
use Path::Tiny qw( path );
with 'Dist::Zilla::Role::Plugin';

has 'on' => (
Expand All @@ -20,13 +22,26 @@ has 'on' => (
default => sub { [] },
);

has 'container' => (
isa => 'Str',
is => 'ro',
lazy_required => 1,
);

has '_on_parsed' => (
isa => 'ArrayRef',
is => 'ro',
lazy => 1,
builder => '_build_on_parsed',
);

has '_container' => (
isa => 'Ref',
is => 'ro',
lazy => 1,
builder => '_build_container',
);

around mvp_multivalue_args => sub {
my ( $orig, $self, @args ) = @_;
return ( qw( on ), $self->$orig(@args) );
Expand All @@ -49,8 +64,11 @@ sub _parse_connector {
if ( $connector =~ /\Aplugin:(.+?)[#]([^#]+)\z/sx ) {
return { type => 'plugin', name => "$1", connection => "$2", };
}
if ( $connector =~ /\Acontainer:(.+?)[#]([^#]+)\z/sx ) {
return { type => 'container', name => "$1", connection => "$2", };
}
croak "Invalid connector specification \"$connector\"\n" #
. q[Didn't match "plugin:<id>#<event|listener>"];
. q[Didn't match "(plugin|container):<id>#<event|listener>"];
}

sub _parse_on_directive {
Expand Down Expand Up @@ -78,12 +96,16 @@ sub _find_connector {
croak "Can't resolve plugin \"$spec->{name}\" to an instance.\n" #
. q[Did the plugin exist? Is the connection *after* it?];
}
if ( 'container' eq $spec->{type} ) {
return $self->_container->get( $spec->{'name'} );
}
croak "Unknown connector type \"$spec->{type}\"";
}

# This is to avoid making the sub a closure that contains the emitter
sub _make_connector {
my ( $recipient, $method_name ) = @_;

# Maybe weak ref? IDK
return sub {
my ($event) = @_;
Expand All @@ -96,8 +118,8 @@ sub _connect {
my $emitter_object = $self->_find_connector($emitter);
my $listener_object = $self->_find_connector($listener);

my $emit_name = $emitter->{name};
my $listen_name = $listener->{name};
my $emit_name = $emitter->{type} . $emitter->{name};
my $listen_name = $listener->{type} . $listener->{name};

my $emit_on = $emitter->{connection};
my $listen_on = $listener->{connection};
Expand All @@ -109,7 +131,7 @@ sub _connect {
croak qq[Listener Target "$listen_name" has no "$listen_on" method to recive events];
}

$self->log_debug(['Connecting %s#<%s> to %s#<%s>', $emit_name, $emit_on, $listen_name, $listen_on ]);
$self->log_debug( [ 'Connecting %s#<%s> to %s#<%s>', $emit_name, $emit_on, $listen_name, $listen_on ] );
$emitter_object->on( $emit_on, _make_connector( $listener_object, $listen_on ) );
return;

Expand All @@ -120,6 +142,15 @@ sub _build_on_parsed {
return [ map { _parse_on_directive($_) } @{ $self->on } ];
}

sub _build_container {
my ($self) = @_;
my $file = $self->container;
require Beam::Wire;
$self->log_debug( [ 'Loading Beam::Wire container from %s', $file ] );
my $wire = Beam::Wire->new( file => path( $self->zilla->root, $file ) );
return $wire;
}

1;

=head1 SYNOPSIS
Expand All @@ -131,6 +162,12 @@ sub _build_on_parsed {
; PluginA emitting event 'foo' passes the event to PluginB
on = plugin:PluginA#foo => plugin:PluginB#handle_foo
on = plugin:PluginA#bar => plugin:PluginB#handle_bar
; Load 'beam.yml' as a Beam::Wire container
container = beam.yml
; Handle Dist::Zilla plugin events with arbitrary classes
; loaded by Beam::Wire
on = plugin:PluginA#foo => container:servicename#handle_foo
on = plugin:PluginA#bar => container:otherservicename#handle_bar
=head1 DESCRIPTION
Expand Down
6 changes: 6 additions & 0 deletions t/example/neomake.t
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,11 @@ is( scalar @matches, 4, "4 lines added referencing Win32" );
is( scalar( grep /MSWin32/i, @matches ), 2, "2 lines added referencing MSWin32" );
is( scalar( grep /Unsupported/i, @matches ), 2, "2 lines added referencing Unsupported" );

my (@messages) = grep /This message brought/i, split /\n/, $file_content;
note explain \@messages;
is( scalar @messages, 2, "2 messages added by non-dzil code!" );
is( scalar( grep /letter G/i, @messages ), 1, "Letter G arrived" );
is( scalar( grep /letter M/i, @messages ), 1, "Letter M arrived" );

done_testing;

0 comments on commit ec28ca6

Please sign in to comment.