File Coverage

blib/lib/Dir/Manifest.pm
Criterion Covered Total %
statement 69 71 97.1
branch 10 12 83.3
condition n/a
subroutine 17 17 100.0
pod 8 8 100.0
total 104 108 96.3


line stmt bran cond sub pod time code
1             package Dir::Manifest;
2             $Dir::Manifest::VERSION = '0.6.0';
3 1     1   56047 use strict;
  1         8  
  1         24  
4 1     1   5 use warnings;
  1         1  
  1         21  
5              
6 1     1   22 use 5.014;
  1         3  
7              
8 1     1   685 use Path::Tiny qw/ path /;
  1         10931  
  1         47  
9 1     1   364 use Dir::Manifest::Key ();
  1         4  
  1         25  
10 1     1   395 use Dir::Manifest::Slurp ();
  1         2  
  1         17  
11              
12 1     1   5 use Moo;
  1         1  
  1         6  
13              
14             has 'manifest_fn' => ( is => 'ro', required => 1 );
15             has 'dir' => ( is => 'ro', required => 1 );
16              
17             my $ALLOWED = qr/[a-zA-Z0-9_\-\.=]/;
18             my $ALPHAN = qr/[a-zA-Z0-9_]/;
19              
20             sub _is_valid_key
21             {
22 19     19   31 my ( $self, $key ) = @_;
23 19 100       109 if ( $key !~ /\A(?:$ALLOWED)+\z/ )
24             {
25 1         9 die
26             "Invalid characters in key \"$key\"! We only allow A-Z, a-z, 0-9, _, dashes and equal signs.";
27             }
28 18 100       64 if ( $key !~ /\A$ALPHAN/ )
29             {
30 1         9 die qq#Key does not start with an alphanumeric - "$key"!#;
31             }
32 17 100       57 if ( $key !~ /$ALPHAN\z/ )
33             {
34 1         9 die qq#Key does not end with an alphanumeric - "$key"!#;
35             }
36              
37 16         28 return;
38             }
39              
40             has '_keys' => (
41             is => 'ro',
42             lazy => 1,
43             default => sub {
44             my $self = shift;
45              
46             my @lines = path( $self->manifest_fn )->lines( { chomp => 1 } );
47             my $ret = +{};
48              
49             foreach my $l (@lines)
50             {
51             $self->_is_valid_key($l);
52             $ret->{$l} = 1;
53             }
54             return $ret;
55             }
56             );
57              
58             has '_dh' => (
59             is => 'ro',
60             lazy => 1,
61             default => sub {
62             my $self = shift;
63             return path( $self->dir );
64             },
65             );
66              
67             sub get_keys
68             {
69 12     12 1 21926 my ($self) = @_;
70              
71 12         14 return [ sort { $a cmp $b } keys %{ $self->_keys } ];
  27         86  
  12         186  
72             }
73              
74             sub get_obj
75             {
76 21     21 1 31 my ( $self, $key ) = @_;
77              
78 21 100       367 if ( not exists $self->_keys->{$key} )
79             {
80 1         14 die "No such key \"$key\"! Perhaps add it to the manifest.";
81             }
82 20         361 return Dir::Manifest::Key->new(
83             { key => $key, fh => $self->_dh->child($key) } );
84             }
85              
86             sub fh
87             {
88 19     19 1 30 my ( $self, $key ) = @_;
89              
90 19         28 return $self->get_obj($key)->fh;
91             }
92              
93             sub text
94             {
95 17     17 1 1678 my ( $self, $key, $opts ) = @_;
96              
97 17         26 return Dir::Manifest::Slurp::slurp( $self->fh($key), $opts );
98             }
99              
100             sub texts_dictionary
101             {
102 5     5 1 1562 my ( $self, $args ) = @_;
103              
104 5         8 my $opts = $args->{slurp_opts};
105              
106 5         8 return +{ map { $_ => $self->text( $_, $opts ) } @{ $self->get_keys } };
  16         47  
  5         10  
107             }
108              
109             sub _update_disk_manifest
110             {
111 2     2   5 my $self = shift;
112              
113 2         7 path( $self->manifest_fn )->spew_raw( map { "$_\n" } @{ $self->get_keys } );
  7         17  
  2         47  
114              
115 2         660 return;
116             }
117              
118             sub add_key
119             {
120 1     1 1 3 my ( $self, $args ) = @_;
121              
122 1         2 my $key = $args->{key};
123 1         2 my $utf8_val = $args->{utf8_val};
124              
125 1 50       21 if ( exists $self->_keys->{$key} )
126             {
127 0         0 die "Key \"$key\" already exists in the dictionary!";
128             }
129              
130 1         10 $self->_is_valid_key($key);
131              
132 1         14 $self->_keys->{$key} = 1;
133              
134 1         9 $self->_update_disk_manifest;
135 1         4 $self->fh($key)->spew_utf8($utf8_val);
136              
137 1         402 return;
138             }
139              
140             sub remove_key
141             {
142 1     1 1 624 my ( $self, $args ) = @_;
143              
144 1         2 my $key = $args->{key};
145              
146 1 50       20 if ( not exists $self->_keys->{$key} )
147             {
148 0         0 die "Key \"$key\" does not exist in the dictionary!";
149             }
150              
151 1         9 $self->fh($key)->remove;
152 1         154 delete $self->_keys->{$key};
153 1         9 $self->_update_disk_manifest;
154              
155 1         2 return;
156             }
157              
158             sub dwim_new
159             {
160 1     1 1 10 my ( $class, $args ) = @_;
161              
162 1         3 my $base = path( $args->{base} );
163              
164 1         27 return $class->new(
165             {
166             manifest_fn => $base->child("list.txt"),
167             dir => $base->child("texts"),
168             }
169             );
170             }
171              
172             1;
173              
174             __END__