File Coverage

blib/lib/Pinto/Schema/Result/Stack.pm
Criterion Covered Total %
statement 251 288 87.1
branch 33 62 53.2
condition 17 43 39.5
subroutine 52 71 73.2
pod 1 44 2.2
total 354 508 69.6


line stmt bran cond sub pod time code
1 54     54   53967 use utf8;
  54         173  
  54         508  
2              
3             package Pinto::Schema::Result::Stack;
4              
5             # Created by DBIx::Class::Schema::Loader
6             # DO NOT MODIFY THE FIRST PART OF THIS FILE
7              
8              
9 54     54   2620 use strict;
  54         147  
  54         1528  
10 54     54   341 use warnings;
  54         134  
  54         1948  
11              
12 54     54   427 use Moose;
  54         135  
  54         485  
13 54     54   399350 use MooseX::NonMoose;
  54         300  
  54         868  
14 54     54   320364 use MooseX::MarkAsMethods autoclean => 1;
  54         132  
  54         553  
15             extends 'DBIx::Class::Core';
16              
17              
18             __PACKAGE__->table("stack");
19              
20              
21             __PACKAGE__->add_columns(
22             "id", { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
23             "name", { data_type => "text", is_nullable => 0 },
24             "is_default", { data_type => "boolean", is_nullable => 0 },
25             "is_locked", { data_type => "boolean", is_nullable => 0 },
26             "properties", { data_type => "text", is_nullable => 0 },
27             "head", { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
28             );
29              
30              
31             __PACKAGE__->set_primary_key("id");
32              
33              
34             __PACKAGE__->add_unique_constraint( "name_unique", ["name"] );
35              
36              
37             __PACKAGE__->belongs_to(
38             "head",
39             "Pinto::Schema::Result::Revision",
40             { id => "head" },
41             { is_deferrable => 0, on_delete => "RESTRICT", on_update => "NO ACTION" },
42             );
43              
44              
45             with 'Pinto::Role::Schema::Result';
46              
47             # Created by DBIx::Class::Schema::Loader v0.07033 @ 2013-03-04 12:39:54
48             # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+O/IwTdVRx98MHUkJ281lg
49              
50             #-------------------------------------------------------------------------------
51              
52             # ABSTRACT: Represents a named set of Packages
53              
54             #-------------------------------------------------------------------------------
55              
56             our $VERSION = '0.14'; # VERSION
57              
58             #-------------------------------------------------------------------------------
59              
60 54     54   295903 use MooseX::Types::Moose qw(Bool Str Undef);
  54         137  
  54         653  
61              
62 54     54   260684 use String::Format;
  54         3818  
  54         3406  
63 54     54   22798 use File::Copy ();
  54         100862  
  54         1478  
64 54     54   16240 use JSON qw(encode_json decode_json);
  54         250833  
  54         630  
65              
66 54     54   8967 use Pinto::Util qw(:all);
  54         127  
  54         3288  
67 54     54   16922 use Pinto::Types qw(Dir File Version);
  54         123  
  54         500  
68              
69 54     54   341122 use version;
  54         224  
  54         422  
70             use overload (
71 54         420 '""' => 'to_string',
72             '<=>' => 'numeric_compare',
73             'cmp' => 'string_compare'
74 54     54   5144 );
  54         133  
75              
76             #------------------------------------------------------------------------------
77              
78             __PACKAGE__->inflate_column(
79             'properties' => {
80             inflate => sub { decode_json( $_[0] || '{}' ) },
81             deflate => sub { encode_json( $_[0] || {} ) }
82             }
83             );
84              
85             #------------------------------------------------------------------------------
86              
87             has stack_dir => (
88             is => 'ro',
89             isa => Dir,
90             lazy => 1,
91             default => sub { $_[0]->repo->config->stacks_dir->subdir( $_[0]->name ) },
92             );
93              
94             has modules_dir => (
95             is => 'ro',
96             isa => Dir,
97             lazy => 1,
98             default => sub { $_[0]->stack_dir->subdir('modules') },
99             );
100              
101             has authors_dir => (
102             is => 'ro',
103             isa => Dir,
104             lazy => 1,
105             default => sub { $_[0]->stack_dir->subdir('authors') },
106             );
107              
108             has description => (
109             is => 'ro',
110             isa => Str | Undef,
111             lazy => 1,
112             default => sub { $_[0]->get_property('description') },
113             init_arg => undef,
114             );
115              
116             has target_perl_version => (
117             is => 'ro',
118             isa => Version,
119             lazy => 1,
120             default => sub {
121             $_[0]->get_property('target_perl_version')
122             or $_[0]->repo->config->target_perl_version;
123             },
124             init_arg => undef,
125             coerce => 1,
126             );
127              
128             #------------------------------------------------------------------------------
129              
130             sub FOREIGNBUILDARGS {
131 129     129 0 498 my ( $class, $args ) = @_;
132              
133 129   50     458 $args ||= {};
134 129   50     971 $args->{is_default} ||= 0;
135 129   50     766 $args->{is_locked} ||= 0;
136 129   50     950 $args->{properties} ||= '{}';
137              
138 129         1020 return $args;
139             }
140              
141             #------------------------------------------------------------------------------
142              
143             before is_default => sub {
144             my ( $self, @args ) = @_;
145             throw "Cannot directly set is_default. Use mark_as_default instead" if @args;
146             };
147              
148             #------------------------------------------------------------------------------
149             # TODO: All methods below that operate on the head should be moved into the
150             # Revision class, since that is where the data actually is. For convenience,
151             # the Stack class can have the same methods, but they should just delegate to
152             # the Revision class.
153             #------------------------------------------------------------------------------
154              
155              
156             sub get_distribution {
157 101     101 1 423 my ( $self, %args ) = @_;
158              
159 101         313 my $cache = $args{cache};
160 101 50       919 my $target = $args{target} or throw 'Invalid arguments';
161 101 50 66     415 return $cache->{$target} if $cache && exists $cache->{$target};
162              
163 101         227 my $dist;
164 101 100       533 if ( itis( $target, 'Pinto::Target::Distribution' ) ) {
    50          
165              
166 5         24 my $attrs = { prefetch => 'distribution'};
167 5         140 my $where = {'distribution.author' => $target->author, 'distribution.archive' => $target->archive};
168              
169 5 100       92 return unless my $reg = $self->head->search_related( registrations => $where, $attrs )->first;
170 2         105 $dist = $reg->distribution;
171             }
172             elsif ( itis( $target, 'Pinto::Target::Package' ) ) {
173              
174 96         505 my $attrs = { prefetch => 'distribution' };
175 96         2378 my $where = { package_name => $target->name };
176              
177 96 100       1899 return unless my $reg = $self->head->find_related( registrations => $where, $attrs );
178 30 100       1442 return unless $target->is_satisfied_by($reg->package->version);
179 26         2163 $dist = $reg->distribution;
180             }
181              
182 28 100       9319 $cache->{$target} = $dist if $cache;
183 28         483 return $dist;
184             }
185              
186             #------------------------------------------------------------------------------
187              
188             sub make_filesystem {
189 137     137 0 3642 my ($self) = @_;
190              
191 137         5410 my $stack_dir = $self->stack_dir;
192 137         934 debug "Making stack directory at $stack_dir";
193 137         791 $stack_dir->mkpath;
194              
195 137         33410 my $stack_modules_dir = $self->modules_dir;
196 137         660 debug "Making modules directory at $stack_modules_dir";
197 137         608 $stack_modules_dir->mkpath;
198              
199 137         17853 my $stack_authors_dir = $self->authors_dir;
200 137         3720 my $shared_authors_dir = $self->repo->config->authors_dir->relative($stack_dir);
201 137         25913 mksymlink( $stack_authors_dir => $shared_authors_dir );
202              
203 137         805 $self->write_modlist;
204              
205 137         913 return $self;
206             }
207              
208             #------------------------------------------------------------------------------
209              
210             sub rename_filesystem {
211 3     3 0 11 my ( $self, %args ) = @_;
212              
213 3         9 my $new_name = $args{to};
214              
215 3         12 $self->assert_not_locked;
216              
217 3         81 my $orig_dir = $self->stack_dir;
218 3 50       18 throw "Directory $orig_dir does not exist"
219             if not -e $orig_dir;
220              
221 3         282 my $new_dir = $self->repo->config->stacks_dir->subdir($new_name);
222 3 100 66     139 throw "Directory $new_dir already exists"
223             if -e $new_dir && (lc $new_dir ne lc $orig_dir);
224              
225 2         95 debug "Renaming directory $orig_dir to $new_dir";
226 2 50       16 File::Copy::move( $orig_dir, $new_dir ) or throw "Rename failed: $!";
227              
228 2         286 return $self;
229             }
230              
231             #------------------------------------------------------------------------------
232              
233             sub kill_filesystem {
234 2     2 0 6 my ($self) = @_;
235              
236 2         8 $self->assert_not_locked;
237              
238 2         51 my $stack_dir = $self->stack_dir;
239 2 50       10 $stack_dir->rmtree or throw "Failed to remove $stack_dir: $!";
240              
241 2         993 return $self;
242             }
243              
244             #------------------------------------------------------------------------------
245              
246             sub duplicate {
247 8     8 0 41 my ( $self, %changes ) = @_;
248              
249 8         37 $changes{is_default} = 0; # Never duplicate the default flag
250              
251 8         346 return $self->copy( \%changes );
252             }
253              
254             #------------------------------------------------------------------------------
255              
256             sub duplicate_registrations {
257 188     188 0 4944 my ( $self, %args ) = @_;
258              
259 188         569 my $new_rev = $args{to};
260 188   66     5674 my $old_rev = $args{from} || $self->head;
261              
262 188         9359 my $new_rev_id = $new_rev->id;
263 188         6103 my $old_rev_id = $old_rev->id;
264              
265 188         2820 debug "Copying registrations for stack $self to $new_rev";
266              
267             # This raw SQL is an optimization. I was using DBIC's HashReinflator
268             # to fetch all the registrations, change the revision, and then reinsert
269             # them as new records using populate(). But that was too slow if there
270             # are lots of registrations.
271              
272 188         1248 my $sql = qq{
273             INSERT INTO registration(revision, package, package_name, distribution, is_pinned)
274             SELECT '$new_rev_id', package, package_name, distribution, is_pinned
275             FROM registration WHERE revision = '$old_rev_id';
276             };
277              
278 188         829 $self->result_source->storage->dbh->do($sql);
279              
280 188         128854 return $self;
281             }
282              
283             #------------------------------------------------------------------------------
284              
285             sub rename {
286 2     2 0 9 my ( $self, %args ) = @_;
287              
288 2         7 my $new_name = $args{to};
289              
290 2         6 $self->assert_not_locked;
291              
292 2         48 $self->update( { name => $new_name } );
293              
294 2         2997 $self->refresh; # Causes moose attributes to be reinitialized
295              
296 2 50       11 $self->repo->link_modules_dir( to => $self->modules_dir ) if $self->is_default;
297              
298 2         8 return $self;
299             }
300              
301             #------------------------------------------------------------------------------
302              
303             sub kill {
304 4     4 0 8 my ($self) = @_;
305              
306 4         17 $self->assert_not_locked;
307              
308 3 100       17 throw "Cannot kill the default stack" if $self->is_default;
309              
310 2         102 $self->delete;
311              
312 2         2646 return $self;
313             }
314              
315             #------------------------------------------------------------------------------
316              
317             sub lock {
318 6     6 0 17 my ($self) = @_;
319              
320 6 50       107 return $self if $self->is_locked;
321              
322 6         141 debug "Locking stack $self";
323              
324 6         90 $self->update( { is_locked => 1 } );
325              
326 6         8155 return $self;
327             }
328              
329             #------------------------------------------------------------------------------
330              
331             sub unlock {
332 2     2 0 7 my ($self) = @_;
333              
334 2 50       48 return $self if not $self->is_locked;
335              
336 2         35 debug "Unlocking stack $self";
337              
338 2         22 $self->update( { is_locked => 0 } );
339              
340 2         2433 return $self;
341             }
342              
343             #------------------------------------------------------------------------------
344              
345             sub set_head {
346 183     183 0 569 my ( $self, $revision ) = @_;
347              
348 183     0   2014 debug sub {"Setting head of stack $self to revision $revision"};
  0         0  
349              
350 183         2239 $self->update( { head => $revision } );
351              
352 183         179988 return $self;
353             }
354              
355             #------------------------------------------------------------------------------
356              
357             sub start_revision {
358 183     183 0 561 my ($self) = @_;
359              
360 183         882 debug "Starting revision on stack $self";
361              
362 183         1199 $self->assert_is_committed;
363              
364 183         4336 my $old_head = $self->head;
365 183         7252 my $new_head = $self->result_source->schema->create_revision( {} );
366              
367 183         374937 $self->duplicate_registrations( to => $new_head );
368              
369 183         1505 $new_head->add_parent($old_head);
370 183         1140 $self->set_head($new_head);
371              
372 183         945 $self->assert_is_open;
373              
374 183         1056 return $self;
375             }
376              
377             #------------------------------------------------------------------------------
378              
379             sub commit_revision {
380 151     151 0 691 my ( $self, %args ) = @_;
381              
382             throw "Must specify a message to commit"
383 151 50 33     800 if not( $args{message} or $self->head->message );
384              
385 151         774 $self->assert_is_open;
386 151         1658 $self->assert_has_changed;
387              
388 151         4334 $self->head->commit(%args);
389 148         1011 $self->write_index;
390              
391 148         1136 $self->assert_is_committed;
392              
393 148         791 return $self;
394             }
395              
396             #-------------------------------------------------------------------------------
397              
398             sub should_keep_history {
399 0     0 0 0 my ($self) = @_;
400              
401             # Is this revision referenced by other stacks?
402 0 0       0 return 1 if $self->head->stacks->count > 1;
403              
404             # Then do not keep history
405 0         0 return 0;
406             }
407              
408             #-------------------------------------------------------------------------------
409              
410             sub package_count {
411 0     0 0 0 my ($self) = @_;
412              
413 0         0 return $self->head->registrations->count;
414             }
415              
416             #-------------------------------------------------------------------------------
417              
418             sub distribution_count {
419 0     0 0 0 my ($self) = @_;
420              
421 0         0 my $attrs = { select => 'distribution', distinct => 1 };
422 0         0 return $self->head->registrations( {}, $attrs )->count;
423             }
424              
425             #------------------------------------------------------------------------------
426              
427             sub assert_is_open {
428 540     540 0 1618 my ($self) = @_;
429              
430 540         12943 return $self->head->assert_is_open;
431             }
432              
433             #------------------------------------------------------------------------------
434              
435             sub assert_is_committed {
436 331     331 0 1173 my ($self) = @_;
437              
438 331         8008 return $self->head->assert_is_committed;
439             }
440              
441             #------------------------------------------------------------------------------
442              
443             sub assert_has_changed {
444 151     151 0 475 my ($self) = @_;
445              
446 151         4422 return $self->head->assert_has_changed;
447             }
448              
449             #------------------------------------------------------------------------------
450              
451             sub assert_not_locked {
452 230     230 0 707 my ($self) = @_;
453              
454 230 100       4863 throw "Stack $self is locked and cannot be modified or deleted"
455             if $self->is_locked;
456              
457 223         3902 return $self;
458             }
459              
460             #------------------------------------------------------------------------------
461              
462             sub set_description {
463 7     7 0 22 my ( $self, $description ) = @_;
464              
465 7         41 $self->set_property( description => $description );
466              
467 7         19 return $self;
468             }
469              
470             #------------------------------------------------------------------------------
471              
472             sub diff {
473 9     9 0 108 my ( $self, $other ) = @_;
474              
475 9   33     275 my $left = $other || ( $self->head->parents )[0];
476 9         296 my $right = $self;
477              
478 9         2702 require Pinto::Difference;
479 9         374 return Pinto::Difference->new( left => $left, right => $right );
480             }
481              
482             #-----------------------------------------------------------------------------
483              
484             sub distributions {
485 2     2 0 6 my ($self) = @_;
486              
487 2         43 return $self->head->distributions;
488             }
489              
490             #-----------------------------------------------------------------------------
491              
492             sub packages {
493 0     0 0 0 my ($self) = @_;
494              
495 0         0 return $self->head->packages;
496             }
497              
498             #-----------------------------------------------------------------------------
499              
500             sub roots {
501 2     2 0 7 my ($self) = @_;
502              
503 2         13 my @dists = $self->distributions->all;
504 2         7243 my $tpv = $self->target_perl_version;
505 2         5 my %is_prereq_dist;
506             my %cache;
507              
508             # Algorithm: Visit each distribution and resolve each of its
509             # dependencies to the prerequisite distribution (if it exists).
510             # Any distribution that is a prerequisite cannot be a root.
511              
512 2         13 for my $dist ( @dists ) {
513 6         3261 for my $prereq ($dist->prerequisites) {
514             # TODO: When we support suggested/recommended prereqs
515             # those will have to be skipped too. See here for more
516             # discussion: https://github.com/thaljef/Pinto/issues/158
517 4 50 33     16340 next if $prereq->is_test or $prereq->is_develop;
518 4 50 33     89 next if $prereq->is_core(in => $tpv) or $prereq->is_perl;
519 4         101 my %args = (target => $prereq->as_target, cache => \%cache);
520 4 50       36 next unless my $prereq_dist = $self->get_distribution(%args);
521 4         130 $is_prereq_dist{$prereq_dist} = 1;
522             }
523             }
524              
525 2         2889 return grep { not $is_prereq_dist{$_} } @dists;
  6         146  
526             }
527              
528             #-----------------------------------------------------------------------------
529              
530             sub mark_as_default {
531 114     114 0 758 my ($self) = @_;
532              
533 114 50       820 return $self if $self->is_default;
534              
535 114         5102 debug 'Marking all stacks as non-default';
536 114         508 my $rs = $self->result_source->resultset->search;
537 114         60073 $rs->update_all( { is_default => 0 } );
538              
539 114         257212 debug "Marking stack $self as default";
540 114         785 $self->update( { is_default => 1 } );
541              
542 114         135566 $self->repo->link_modules_dir( to => $self->modules_dir );
543              
544 114         599 return 1;
545             }
546              
547             #------------------------------------------------------------------------------
548              
549             sub unmark_as_default {
550 2     2 0 6 my ($self) = @_;
551              
552 2 50       9 return $self if not $self->is_default;
553              
554 2         82 debug "Unmarking stack $self as default";
555              
556 2         52 $self->update( { is_default => 0 } );
557              
558 2         2654 $self->repo->unlink_modules_dir;
559              
560 2         16 return 1;
561             }
562              
563             #------------------------------------------------------------------------------
564              
565             sub mark_as_changed {
566 205     205 0 26258 my ($self) = @_;
567              
568 205         15273 debug "Marking stack $self as changed";
569              
570 205         5119 $self->head->update( { has_changes => 1 } );
571              
572 205         224489 return $self;
573             }
574              
575             #------------------------------------------------------------------------------
576              
577             sub has_changed {
578 166     166 0 466 my ($self) = @_;
579              
580 166         3910 return $self->head->refresh->has_changes;
581             }
582              
583             #------------------------------------------------------------------------------
584              
585             sub has_not_changed {
586 162     162 0 566 my ($self) = @_;
587              
588 162         746 return !$self->has_changed;
589             }
590              
591             #------------------------------------------------------------------------------
592              
593             sub write_index {
594 285     285 0 909 my ($self) = @_;
595              
596 285         24357 require Pinto::IndexWriter;
597 285         10941 my $writer = Pinto::IndexWriter->new( stack => $self );
598 285         1620 $writer->write_index;
599              
600 285         19266 return $self;
601             }
602              
603             #------------------------------------------------------------------------------
604              
605             sub write_modlist {
606 137     137 0 432 my ($self) = @_;
607              
608 137         23411 require Pinto::ModlistWriter;
609 137         4931 my $writer = Pinto::ModlistWriter->new( stack => $self );
610 137         750 $writer->write_modlist;
611              
612 137         5637 return $self;
613             }
614              
615             #------------------------------------------------------------------------------
616              
617             sub get_property {
618 334     334 0 1374 my ( $self, @prop_keys ) = @_;
619              
620 334         767 my %props = %{ $self->get_properties };
  334         1451  
621              
622 334         1320 return @props{ map {lc} @prop_keys };
  334         12435  
623             }
624              
625             #-------------------------------------------------------------------------------
626              
627             sub get_properties {
628 341     341 0 1392 my ($self) = @_;
629              
630 341         765 my %props = %{ $self->properties }; # Making a copy!
  341         7777  
631              
632 341         2447 return \%props;
633             }
634              
635             #-------------------------------------------------------------------------------
636              
637             sub set_property {
638 11     11 0 420 my ( $self, $key, $value ) = @_;
639              
640 11         73 $self->set_properties( { $key => "$value" } );
641              
642 10         46 return $self;
643             }
644              
645             #-------------------------------------------------------------------------------
646              
647             sub set_properties {
648 140     140 0 494 my ( $self, $new_props ) = @_;
649              
650 140         3468 my $props = $self->properties;
651 140         7245 while ( my ( $key, $value ) = each %{$new_props} ) {
  408         1751  
652 269         1430 Pinto::Util::validate_property_name($key);
653              
654 268 100 66     1624 if ( defined $value && length "$value" ) {
655 267         1162 $props->{ lc $key } = "$value";
656             }
657             else {
658 1         6 delete $props->{ lc $key };
659             }
660             }
661              
662 139         5285 $self->update( { properties => $props } );
663              
664 139         236328 return $self;
665             }
666              
667             #-------------------------------------------------------------------------------
668              
669             sub delete_property {
670 2     2 0 10 my ( $self, @prop_keys ) = @_;
671              
672 2         48 my $props = $self->properties;
673 2         63 delete $props->{ lc $_ } for @prop_keys;
674              
675 2         18 $self->update( { properties => $props } );
676              
677 2         24023 return $self;
678             }
679              
680             #-------------------------------------------------------------------------------
681              
682             sub delete_properties {
683 0     0 0 0 my ($self) = @_;
684              
685 0         0 self->update( { properties => {} } );
686              
687 0         0 return $self;
688             }
689              
690             #-------------------------------------------------------------------------------
691              
692             sub default_properties {
693 128     128 0 436 my ($self) = @_;
694              
695 128         3127 my $desc = sprintf( 'The %s stack', $self->name );
696 128         6945 my $tpv = $self->repo->config->target_perl_version->stringify;
697              
698             return {
699 128         1273 description => $desc,
700             target_perl_version => $tpv
701             };
702             }
703              
704             #-----------------------------------------------------------------------------
705              
706             sub numeric_compare {
707 0     0 0 0 my ( $stack_a, $stack_b ) = @_;
708              
709 0         0 my $pkg = __PACKAGE__;
710 0 0 0     0 throw "Can only compare $pkg objects"
711             if not( itis( $stack_a, $pkg ) && itis( $stack_b, $pkg ) );
712              
713 0 0       0 return 0 if $stack_a->id == $stack_b->id;
714              
715 0         0 my $r = ( $stack_a->head <=> $stack_b->head );
716              
717 0         0 return $r;
718             }
719              
720             #-----------------------------------------------------------------------------
721              
722             sub string_compare {
723 0     0 0 0 my ( $stack_a, $stack_b ) = @_;
724              
725 0         0 my $pkg = __PACKAGE__;
726 0 0 0     0 throw "Can only compare $pkg objects"
727             if not( itis( $stack_a, $pkg ) && itis( $stack_b, $pkg ) );
728              
729 0 0       0 return 0 if $stack_a->id == $stack_b->id;
730              
731 0         0 my $r = ( $stack_a->name cmp $stack_b->name );
732              
733 0         0 return $r;
734             }
735              
736             #------------------------------------------------------------------------------
737              
738             sub to_string {
739 2650     2650 0 2099220 my ( $self, $format ) = @_;
740              
741             my %fspec = (
742 2650     2650   198796 k => sub { $self->name },
743 0 0   0   0 M => sub { $self->is_default ? '*' : ' ' },
744 0 0   0   0 L => sub { $self->is_locked ? '!' : ' ' },
745 0     0   0 I => sub { $self->head->uuid },
746 0     0   0 i => sub { $self->head->uuid_prefix },
747 0     0   0 g => sub { $self->head->message },
748 0     0   0 G => sub { indent_text( trim_text( $self->head->message ), $_[0] ) },
749 0     0   0 t => sub { $self->head->message_title },
750 0     0   0 T => sub { truncate_text( $self->head->message_title, $_[0] ) },
751 0     0   0 b => sub { $self->head->message_body },
752 0     0   0 j => sub { $self->head->username },
753 0   0 0   0 u => sub { $self->head->datetime_local->strftime( $_[0] || '%c' ) },
754 2650         71747 );
755              
756 2650   33     19778 $format ||= $self->default_format();
757 2650         16935 return String::Format::stringf( $format, %fspec );
758             }
759              
760             #-------------------------------------------------------------------------------
761              
762             sub default_format {
763 2650     2650 0 6349 my ($self) = @_;
764              
765 2650         10909 return '%k';
766             }
767              
768             #-------------------------------------------------------------------------------
769              
770             __PACKAGE__->meta->make_immutable;
771              
772             #-------------------------------------------------------------------------------
773             1;
774              
775             __END__
776              
777             =pod
778              
779             =encoding UTF-8
780              
781             =for :stopwords Jeffrey Ryan Thalhammer
782              
783             =head1 NAME
784              
785             Pinto::Schema::Result::Stack - Represents a named set of Packages
786              
787             =head1 VERSION
788              
789             version 0.14
790              
791             =head1 METHODS
792              
793             =head2 get_distribution( target => $target )
794              
795             Given a L<Pinto::Target::Package>, returns the L<Pinto::Schema::Result::Distribution>
796             which contains the package with the same name as the target B<and the same or higher
797             version as the target>. Returns nothing if no such distribution is found in
798             this stack.
799              
800             Given a L<Pinto::Target::Distribution>, returns the L<Pinto::Schema::Result::Distribution>
801             from this stack with the same author id and archive attributes as the target.
802             Returns nothing if no such distribution is found in this stack.
803              
804             You can also pass a C<cache> argument that must be a reference to a hash. It will
805             be used to cache results so that repeated calls to C<get_distribution> require
806             fewer trips to the database. It is up to you to decide when to expire the cache.
807              
808             =head1 NAME
809              
810             Pinto::Schema::Result::Stack
811              
812             =head1 TABLE: C<stack>
813              
814             =head1 ACCESSORS
815              
816             =head2 id
817              
818             data_type: 'integer'
819             is_auto_increment: 1
820             is_nullable: 0
821              
822             =head2 name
823              
824             data_type: 'text'
825             is_nullable: 0
826              
827             =head2 is_default
828              
829             data_type: 'boolean'
830             is_nullable: 0
831              
832             =head2 is_locked
833              
834             data_type: 'boolean'
835             is_nullable: 0
836              
837             =head2 properties
838              
839             data_type: 'text'
840             is_nullable: 0
841              
842             =head2 head
843              
844             data_type: 'integer'
845             is_foreign_key: 1
846             is_nullable: 0
847              
848             =head1 PRIMARY KEY
849              
850             =over 4
851              
852             =item * L</id>
853              
854             =back
855              
856             =head1 UNIQUE CONSTRAINTS
857              
858             =head2 C<name_unique>
859              
860             =over 4
861              
862             =item * L</name>
863              
864             =back
865              
866             =head1 RELATIONS
867              
868             =head2 head
869              
870             Type: belongs_to
871              
872             Related object: L<Pinto::Schema::Result::Revision>
873              
874             =head1 L<Moose> ROLES APPLIED
875              
876             =over 4
877              
878             =item * L<Pinto::Role::Schema::Result>
879              
880             =back
881              
882             =head1 AUTHOR
883              
884             Jeffrey Ryan Thalhammer <jeff@stratopan.com>
885              
886             =head1 COPYRIGHT AND LICENSE
887              
888             This software is copyright (c) 2015 by Jeffrey Ryan Thalhammer.
889              
890             This is free software; you can redistribute it and/or modify it under
891             the same terms as the Perl 5 programming language system itself.
892              
893             =cut