File Coverage

blib/lib/App/hopen/Asset.pm
Criterion Covered Total %
statement 31 34 91.1
branch 8 14 57.1
condition 2 6 33.3
subroutine 8 8 100.0
pod 3 3 100.0
total 52 65 80.0


line stmt bran cond sub pod time code
1             # App::hopen::Asset - record representing a file to be produced
2             package App::hopen::Asset;
3 3     3   22 use strict;
  3         7  
  3         91  
4 3     3   16 use Data::Hopen::Base;
  3         5  
  3         20  
5              
6 3     3   4730 use Path::Class;
  3         54231  
  3         921  
7             # and we use Class::Tiny below.
8              
9             our $VERSION = '0.000011';
10              
11             # Docs {{{1
12              
13             =head1 NAME
14              
15             App::hopen::Asset - record representing a file to be produced
16              
17             =head1 SYNOPSIS
18              
19             An asset is something to be produced, e.g., a file on disk or something
20             else that could be a target in a Makefile.
21              
22             =head1 ATTRIBUTES
23              
24             =head2 target
25              
26             TODO: should on-disk targets be required to be BasedPath instances?
27              
28             The name of the asset. Must be one of:
29              
30             =over
31              
32             =item *
33              
34             A L<Path::Class> instance, representing a file or directory on disk
35              
36             =item *
37              
38             An L<App::hopen::Util::BasedPath> instance, representing a file or directory
39             on disk
40              
41             =item *
42              
43             Something that stringifies to a non-disk target (e.g., a goal). Anything in
44             this category will be stored as its stringified value, NOT as its original
45             value.
46              
47             =back
48              
49             No default, so don't call C<< $obj->target >> until you've assigned a target!
50              
51             =head2 made_by
52              
53             The L<App::hopen::G::Cmd> (or subclass) instance that produced this asset.
54             Used to distinguish assets from different sources.
55              
56             =head2 name
57              
58             An optional asset name. If you don't specify one, a unique one will be
59             generated automatically.
60              
61             =head1 METHODS
62              
63             =cut
64              
65             # }}}1
66              
67             # The accessor for the target attribute.
68             sub target {
69 40     40 1 6968 my $self = shift;
70 40 100       115 if (@_) {
    50          
71 7         13 my $candidate = shift;
72 7 50       28 croak "targets must not be falsy" unless $candidate;
73 7 50 33     205 if(eval { $candidate->DOES('Path::Class::File') ||
  7 50       123  
74             $candidate->DOES('Path::Class::Dir') ||
75             $candidate->DOES('App::hopen::Util::BasedPath' ) }
76             ) {
77 7         25 return $self->{target} = $candidate;
78             } else {
79 0         0 return $self->{target} = "$candidate";
80             }
81             } elsif ( exists $self->{target} ) {
82 33         307 return $self->{target};
83             } else { # No default.
84 0         0 croak "I don't have a target to give you";
85             }
86             } #target()
87              
88             # Create the accessor that enforces the restriction on made_by
89             use Class::Tiny::ConstrainedAccessor [NOBUILD => true],
90 10         75 made_by => [ sub { eval { $_[0]->DOES('App::hopen::G::Cmd') } },
  10         103  
91 3     3   485 sub { 'made_by values must implement App::hopen::G::Cmd' } ];
  3         1376  
  3         38  
  0         0  
92              
93             # Set up the rest of the class
94 3     3   390 use Class::Tiny qw(target made_by name);
  3         8  
  3         17  
95              
96             =head2 isdisk
97              
98             Returns truthy if the L</target> is an on-disk entity, i.e., a
99             directory or file.
100              
101             =cut
102              
103             sub isdisk {
104 4 50   4 1 16 my $self = shift or croak 'Need an instance';
105 4   33     13 return ($self->target->DOES('Path::Class::File') ||
106             $self->target->DOES('Path::Class::Dir') ||
107             $self->target->DOES('App::hopen::Util::BasedPath')
108             );
109             } #isdisk()
110              
111             =head2 BUILD
112              
113             Enforces the requirement for C<target> and C<made_by>.
114              
115             =cut
116              
117             my $_id_counter;
118              
119             sub BUILD {
120 7     7 1 406 my ($self) = @_;
121 7 50       141 $self->name('__R_Asset_' . $_id_counter++) unless $self->name;
122 7         206 $self->target($self->{target}); # Check the custom constraint on target
123             # by re-setting target.
124 7         34 $self->_check_all_constraints(); # Checks made_by.
125             } #BUILD()
126              
127             1;
128             __END__
129             # vi: set fdm=marker: #