Skip to content

Commit

Permalink
Move much of the logic out to Config::MVP::Slicer
Browse files Browse the repository at this point in the history
  • Loading branch information
rwstauner committed Oct 18, 2011
1 parent 2fffdae commit c302620
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 68 deletions.
2 changes: 2 additions & 0 deletions Changes
Expand Up @@ -2,6 +2,8 @@ Revision history for Dist::Zilla::Role::Stash::Plugins

{{$NEXT}}

- Move much of the logic out to Config::MVP::Slicer

1.003 2011-07-15T00:41:43Z

- Superficial dist/release changes
Expand Down
102 changes: 36 additions & 66 deletions lib/Dist/Zilla/Role/Stash/Plugins.pm
Expand Up @@ -5,6 +5,7 @@ use warnings;
package Dist::Zilla::Role::Stash::Plugins;
# ABSTRACT: A Stash that stores arguments for plugins

use Config::MVP::Slicer ();
use Moose::Role;
with qw(
Dist::Zilla::Role::DynamicConfig
Expand Down Expand Up @@ -62,19 +63,36 @@ consider L</get_stashed_config> or L</merge_stashed_config>.

# _config inherited

=method get_stashed_config
=attr slicer
Instance of C<Config::MVP::Slicer>
which handles plugin configuration extraction.
Return a hashref of the config arguments for the plugin
determined by C<< ref($plugin) >>.
=cut

This is a slice of the I<_config> attribute
appropriate for the plugin passed to the method.
has slicer => (
is => 'ro',
isa => 'Config::MVP::Slicer',
default => sub {
my $self = shift;
Config::MVP::Slicer->new({
config => $self->_config,
separator => $self->argument_separator,
match_package => sub { $self->expand_package($_[0]) eq $_[1] },
})
},
);

=method get_stashed_config
Return a hashref of the config arguments for the plugin.
This is a thin wrapper around L<Config::MVP::Slicer/slice>.
# with a stash of:
# _config => {
# 'APlug:attr1' => 'value1',
# 'APlug:second' => '2nd',
# 'OtherPlug:attr => '0'
# 'APlug.attr1' => 'value1',
# 'APlug.second' => '2nd',
# 'OtherPlug.attr => '0'
# }
# from inside Dist::Zilla::Plugin::APlug
Expand All @@ -93,30 +111,8 @@ appropriate for the plugin passed to the method.
sub get_stashed_config {
my ($self, $plugin) = @_;

# use ref() rather than $plugin->plugin_name() because we want to match
# the full package name as returned by expand_package() below
# rather than '@Bundle/ShortPluginName'
my $name = ref($plugin);

my $config = $self->_config;
my $stashed = {};
my $splitter = qr/${\ $self->argument_separator }/;

while( my ($key, $value) = each %$config ){
my ($plug, $attr) = ($key =~ $splitter);

unless($plug && $attr){
warn("[${\ ref($self) }] '$key' did not match $splitter. " .
"Do you need a more specific 'argument_separator'?\n");
next;
}

my $pack = $self->expand_package($plug);

$stashed->{$attr} = $value
if $pack eq $name;
}
return $stashed;
return $self->slicer->slice($plugin);
}

=method merge_stashed_config
Expand All @@ -128,9 +124,7 @@ then attempt to merge it into the plugin.
This require the plugin's attributes to be writable (C<'rw'>).
It will attempt to push onto array references and
concatenate onto existing strings (joined by a space).
It will overwrite any other types.
This is a thin wrapper around L<Config::MVP::Slicer/merge>.
Possible options:
Expand All @@ -146,38 +140,9 @@ sub merge_stashed_config {
$opts ||= {};
$opts->{join} = ' '
if !exists $opts->{join};
my $stashed = $opts->{stashed} || $self->get_stashed_config($plugin);

while( my ($key, $value) = each %$stashed ){
# call attribute writer (attribute must be 'rw'!)
my $attr = $plugin->meta->find_attribute_by_name($key);
if( !$attr ){
warn("[${\ ref($self) }] skipping '$key' attribute: " .
"not found on ${\ ref($plugin) }\n");
next;
}
my $type = $attr->type_constraint;
my $previous = $plugin->$key;
if( $previous ){
if( UNIVERSAL::isa($previous, 'ARRAY') ){
push(@$previous, $value);
}
elsif( $type->name eq 'Str' ){
# TODO: pass in string for joining
$plugin->$key(join($opts->{join}, $previous, $value));
}
#elsif( $type->name eq 'Bool' )
else {
$plugin->$key($value);
}
}
else {
$value = [$value]
if $type->name =~ /^arrayref/i;

$plugin->$key($value);
}
}
$opts->{stashed} ||= $self->get_stashed_config($plugin);
$opts->{slice} = delete $opts->{stashed};
return $self->slicer->merge($plugin, $opts);
}

=method separate_local_config
Expand Down Expand Up @@ -216,4 +181,9 @@ that stores arguments for other plugins.
Stashes performing this role must define I<expand_package>.
=head1 SEE ALSO
=for :list
* L<Config::MVP::Slicer>
=cut
5 changes: 3 additions & 2 deletions t/ini-config.t
Expand Up @@ -55,13 +55,14 @@ foreach my $dir ( keys %confs ){
my $mods = defined($confs{$dir}) ? delete($confs{$dir}->{mods}) : undef;

my $stash = $zilla->stash_named('%Test');
is_deeply($stash, $confs{$dir}, "stash matches in $dir")
my @fields = qw(argument_separator _config);
is_deeply([@$stash{@fields}], [@{$confs{$dir}}{@fields}], "stash matches in $dir")
or diag explain [$stash => not => $confs{$dir}];

next unless $mods;

foreach my $mod ( keys %$mods ){
$mock->fake_module($mod, new => sub { bless {}, $_[0] });
$mock->fake_module($mod, new => sub { bless {name => ($_[0] =~ /Test::(.+)$/)[0]}, $_[0] }, plugin_name => sub { shift->{name} });
my $plug = $mod->new();
isa_ok($plug, $mod);
my $stash = $zilla->stash_named('%Test')->get_stashed_config($plug);
Expand Down

0 comments on commit c302620

Please sign in to comment.