Permalink
Browse files

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

  • Loading branch information...
1 parent 2fffdae commit c30262043daf64c297f74ce67e23547e9d9766b0 @rwstauner committed Oct 18, 2011
Showing with 41 additions and 68 deletions.
  1. +2 −0 Changes
  2. +36 −66 lib/Dist/Zilla/Role/Stash/Plugins.pm
  3. +3 −2 t/ini-config.t
View
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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:
@@ -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
@@ -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
View
@@ -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);

0 comments on commit c302620

Please sign in to comment.