File Coverage

blib/lib/Gentoo/Overlay/Group.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1 2     2   81101 use strict;
  2         6  
  2         88  
2 2     2   12 use warnings;
  2         4  
  2         109  
3              
4             package Gentoo::Overlay::Group;
5             BEGIN {
6 2     2   65 $Gentoo::Overlay::Group::AUTHORITY = 'cpan:KENTNL';
7             }
8             {
9             $Gentoo::Overlay::Group::VERSION = '0.2.0';
10             }
11              
12             # ABSTRACT: A collection of Gentoo::Overlay objects.
13              
14 2     2   5322 use Moose;
  0            
  0            
15              
16             use MooseX::Has::Sugar;
17             use MooseX::Types::Moose qw( :all );
18             use MooseX::Types::Path::Tiny qw( Dir );
19             use namespace::autoclean;
20              
21             use Gentoo::Overlay v1.0.3;
22             use Gentoo::Overlay::Types qw( :all );
23             use Gentoo::Overlay::Exceptions qw( :all );
24             use Scalar::Util qw( blessed );
25              
26              
27              
28             has '_overlays' => (
29             ro, lazy,
30             isa => HashRef [Gentoo__Overlay_Overlay],
31             traits => [qw( Hash )],
32             default => sub { return {} },
33             handles => {
34             _has_overlay => exists =>,
35             overlay_names => keys =>,
36             overlays => elements =>,
37             get_overlay => get =>,
38             _set_overlay => set =>,
39             },
40             );
41              
42             my $_str = Str();
43              
44              
45             sub _type_print {
46             return
47             ref $_ ? ref $_
48             : defined $_ ? 'scalar<' . $_ . '>'
49             : 'scalar=undef'
50              
51             }
52              
53              
54             sub add_overlay {
55             my ( $self, @args ) = @_;
56             if ( @args == 1 and blessed $args[0] ) {
57             goto $self->can('_add_overlay_object');
58             }
59             if ( $_str->check( $args[0] ) ) {
60             goto $self->can('_add_overlay_string_path');
61             }
62             return exception(
63             ident => 'bad overlay type',
64             message => qq{Unrecognised parameter types passed to add_overlay. Expected: \n%{signatures}s. Got: [%{type}s]},
65             payload => {
66             signatures => ( join q{}, map { qq{ \$group->add_overlay( $_ );\n} } qw( Str Path::Tiny Gentoo::Overlay ) ),
67             type => ( join q{,}, map { _type_print } @args ),
68             }
69             );
70             }
71              
72              
73             sub iterate {
74             my ( $self, $what, $callback ) = @_;
75             my %method_map = (
76             ebuilds => _iterate_ebuilds =>,
77             categories => _iterate_categories =>,
78             packages => _iterate_packages =>,
79             overlays => _iterate_overlays =>,
80             );
81             if ( exists $method_map{$what} ) {
82             goto $self->can( $method_map{$what} );
83             }
84             return exception(
85             ident => 'bad iteration method',
86             message => 'The iteration method %{what_method}s is not a known way to iterate.',
87             payload => { what_method => $what, },
88             );
89             }
90              
91              
92             sub _iterate_ebuilds {
93             my ( $self, $what, $callback ) = @_;
94             my $real_callback = sub {
95             my (%package_config) = %{ $_[1] };
96             my $inner_callback = sub {
97             my (%ebuild_config) = %{ $_[1] };
98             $self->$callback( { ( %package_config, %ebuild_config ) } );
99             };
100             $package_config{package}->_iterate_ebuilds( ebuilds => $inner_callback );
101             };
102             $self->_iterate_packages( packages => $real_callback );
103             return;
104             }
105              
106              
107             # categories = { /overlays/categories
108              
109             sub _iterate_categories {
110             my ( $self, $what, $callback ) = @_;
111             my $real_callback = sub {
112             my (%overlay_config) = %{ $_[1] };
113             my $inner_callback = sub {
114             my (%category_config) = %{ $_[1] };
115             $self->$callback( { ( %overlay_config, %category_config ) } );
116             };
117             $overlay_config{overlay}->_iterate_categories( categories => $inner_callback );
118             };
119             $self->_iterate_overlays( overlays => $real_callback );
120             return;
121             }
122              
123              
124             sub _iterate_packages {
125             my ( $self, $what, $callback ) = @_;
126             my $real_callback = sub {
127             my (%category_config) = %{ $_[1] };
128             my $inner_callback = sub {
129             my (%package_config) = %{ $_[1] };
130             $self->$callback( { ( %category_config, %package_config ) } );
131             };
132             $category_config{category}->_iterate_packages( packages => $inner_callback );
133             };
134             $self->_iterate_categories( categories => $real_callback );
135             return;
136             }
137              
138              
139             # overlays = { /overlays }
140             sub _iterate_overlays {
141             my ( $self, $what, $callback ) = @_;
142             my %overlays = $self->overlays;
143             my $num_overlays = scalar keys %overlays;
144             my $last_overlay = $num_overlays - 1;
145             my $offset = 0;
146             for my $overlay_name ( sort keys %overlays ) {
147             local $_ = $overlays{$overlay_name};
148             $self->$callback(
149             {
150             overlay_name => $overlay_name,
151             overlay => $overlays{$overlay_name},
152             num_overlays => $num_overlays,
153             last_overlay => $last_overlay,
154             overlay_num => $offset,
155             }
156             );
157             $offset++;
158             }
159             return;
160             }
161              
162             my $_gentoo_overlay = Gentoo__Overlay_Overlay();
163             my $_path_class_dir = Dir();
164              
165             # This would be better in M:M:TypeCoercion
166              
167              
168             sub __can_corce {
169             my ( $to_type, $from_thing ) = @_;
170             if ( not defined $to_type->{_compiled_can_coerce} ) {
171             my @coercion_map = @{ $to_type->type_coercion_map };
172             my @coercions;
173             while (@coercion_map) {
174             my ( $constraint_name, $action ) = ( splice @coercion_map, 0, 2 );
175             my $type_constraint =
176             ref $constraint_name ? $constraint_name : Moose::Util::TypeConstraints::find_or_parse_type_constraint($constraint_name);
177              
178             if ( not defined $type_constraint ) {
179             require Moose;
180             Moose->throw_error("Could not find the type constraint ($constraint_name) to coerce from");
181             }
182              
183             push @coercions => [ $type_constraint->_compiled_type_constraint, $action ];
184             }
185             $to_type->{_compiled_can_coerce} = sub {
186             my $thing = shift;
187             foreach my $coercion (@coercions) {
188             my ( $constraint, $converter ) = @{$coercion};
189             if ( $constraint->($thing) ) {
190             return 1;
191             }
192             }
193             return;
194             };
195             }
196             return $to_type->{_compiled_can_coerce}->($from_thing);
197             }
198              
199              
200             sub _add_overlay_object {
201             my ( $self, $object, @rest ) = @_;
202              
203             if ( $_gentoo_overlay->check($object) ) {
204             goto $self->can('_add_overlay_gentoo_object');
205             }
206             if ( $_path_class_dir->check($object) ) {
207             goto $self->can('_add_overlay_path_class');
208             }
209             return exception(
210             ident => 'bad overlay object type',
211             message => qq{Unrecognised parameter object types passed to add_overlay. Expected: \n%{signatures}s. Got: [%{type}s]},
212             payload => {
213             signatures => ( join q{}, map { qq{ \$group->add_overlay( $_ );\n} } qw( Str Path::Tiny Gentoo::Overlay ) ),
214             type => ( join q{,}, blessed $object, map { _type_print } @rest ),
215             },
216             );
217             }
218              
219              
220             sub _add_overlay_gentoo_object {
221             my ( $self, $object, @rest ) = @_;
222             $_gentoo_overlay->assert_valid($object);
223             if ( $self->_has_overlay( $object->name ) ) {
224             return exception(
225             ident => 'overlay exists',
226             message => 'The overlay named %{overlay_name}s is already added to this group.',
227             payload => { overlay_name => $object->name },
228             );
229             }
230             $self->_set_overlay( $object->name, $object );
231             return;
232             }
233              
234              
235             sub _add_overlay_path_class { ## no critic ( RequireArgUnpacking )
236             my ( $self, $path, @rest ) = @_;
237             $_path_class_dir->assert_valid($path);
238             my $go = Gentoo::Overlay->new( path => $path, );
239             @_ = ( $self, $go );
240             goto $self->can('_add_overlay_gentoo_object');
241             }
242              
243              
244             sub _add_overlay_string_path { ## no critic ( RequireArgUnpacking )
245             my ( $self, $path_str, @rest ) = @_;
246             $_str->assert_valid($path_str);
247             my $path = $_path_class_dir->coerce($path_str);
248             @_ = ( $self, $path );
249             goto $self->can('_add_overlay_path_class');
250             }
251              
252             __PACKAGE__->meta->make_immutable;
253             no Moose;
254              
255             1;
256              
257             __END__
258              
259             =pod
260              
261             =head1 NAME
262              
263             Gentoo::Overlay::Group - A collection of Gentoo::Overlay objects.
264              
265             =head1 VERSION
266              
267             version 0.2.0
268              
269             =head1 SYNOPSIS
270              
271             This is a wrapper around L<< C<Gentoo::Overlay>|Gentoo::Overlay >> that makes it easier to perform actions on a group of overlays.
272              
273             my $group = Gentoo::Overlay::Group->new();
274             $group->add_overlay('/usr/portage');
275             $group->add_overlay('/usr/local/portage/');
276             $group->iterate( packages => sub {
277             my ( $self, $context ) = @_;
278             # Traverse-Order:
279             # ::gentoo
280             # category_a
281             # package_a
282             # package_b
283             # category_b
284             # package_a
285             # package_b
286             # ::hentoo
287             # category_a
288             # package_a
289             # package_b
290             # category_b
291             # package_a
292             # package_b
293             });
294              
295             =head1 METHODS
296              
297             =head2 add_overlay
298              
299             $object->add_overlay( '/path/to/overlay' );
300             $object->add_overlay( Path::Tiny::path( '/path/to/overlay' ) );
301             $object->add_overlay( Gentoo::Overlay->new( path => '/path/to/overlay' ) );
302              
303             =head2 iterate
304              
305             $object->iterate( ebuilds => sub {
306              
307              
308             });
309              
310             =head1 ATTRIBUTE ACCESSORS
311              
312             =head2 overlay_names
313              
314             my @names = $object->overlay_names
315              
316             =head2 overlays
317              
318             my @overlays = $object->overlays;
319              
320             =head2 get_overlay
321              
322             my $overlay = $object->get_overlay('gentoo');
323              
324             =head1 PRIVATE ATTRIBUTES
325              
326             =head2 _overlays
327              
328             isa => HashRef[ Gentoo__Overlay_Overlay ], ro, lazy
329              
330             =head1 PRIVATE ATTRIBUTE ACCESSORS
331              
332             =head2 _has_overlay
333              
334             if( $object->_has_overlay('gentoo') ){
335             Carp::croak('waah');
336             }
337              
338             =head2 _set_overlay
339              
340             $object->_set_overlay( 'gentoo' => $overlay_object );
341              
342             =head1 PRIVATE FUNCTIONS
343              
344             =head2 _type_print
345              
346             Lightweight flat dumper optimized for displaying user parameters in a format similar to a method signature.
347              
348             printf '[%s]', join q{,} , map { _type_print } @array
349              
350             =head2 __can_coerce
351              
352             if( __can_coerce( MX::Type Object , $thing_to_coerce ) ) {
353              
354             }
355              
356             =head1 PRIVATE METHODS
357              
358             =head2 _iterate_ebuilds
359              
360             $object->_iterate_ebuilds( ignored => sub { } );
361              
362             =head2 _iterate_categories
363              
364             $object->_iterate_categories( ignored => sub { } );
365              
366             =head2 _iterate_packages
367              
368             $object->_iterate_packages( ignored => sub { } );
369              
370             =head2 _iterate_overlays
371              
372             $object->_iterate_overlays( ignored => sub { } );
373              
374             =head2 _add_overlay_object
375              
376             $groupobject->_add_overlay_object( $object );
377              
378             =head2 _add_overlay_gentoo_object
379              
380             $groupobject->_add_overlay_gentoo_object( $gentoo_object );
381              
382             =head2 _add_overlay_path_class
383              
384             $groupobject->_add_overlay_path_class( $path_class_object );
385              
386             =head2 _add_overlay_string_path
387              
388             $groupobject->_add_overlay_string_path( $path_string );
389              
390             =head1 AUTHOR
391              
392             Kent Fredric <kentnl@cpan.org>
393              
394             =head1 COPYRIGHT AND LICENSE
395              
396             This software is copyright (c) 2013 by Kent Fredric <kentnl@cpan.org>.
397              
398             This is free software; you can redistribute it and/or modify it under
399             the same terms as the Perl 5 programming language system itself.
400              
401             =cut