File Coverage

blib/lib/CopyTree/VendorProof.pm
Criterion Covered Total %
statement 45 132 34.0
branch 9 58 15.5
condition 1 12 8.3
subroutine 10 15 66.6
pod 10 10 100.0
total 75 227 33.0


line stmt bran cond sub pod time code
1             package CopyTree::VendorProof;
2              
3 1     1   38224 use 5.008000;
  1         4  
  1         31  
4 1     1   5 use strict;
  1         1  
  1         29  
5 1     1   4 use warnings;
  1         6  
  1         61  
6              
7              
8              
9             # Items to export into callers namespace by default. Note: do not export
10             # names by default without a very good reason. Use EXPORT_OK instead.
11             # Do not simply export all your public functions/methods/constants.
12              
13             # This allows declaration use CopyTree::VendorProof ':all';
14             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
15             # will save memory.
16              
17             our $VERSION = '0.0013';
18              
19 1     1   5 use Carp();
  1         2  
  1         22  
20 1     1   1258 use Data::Dumper;
  1         11473  
  1         1507  
21             # Preloaded methods go here.
22              
23             sub new{
24 4     4 1 2410 my $class = shift;
25            
26 4         37 bless {source =>{}, destination =>{}}, $class;
27              
28             }
29             sub reset{
30 1     1 1 502 my $inst=shift;
31 1         4 $inst->{'source'}={};
32 1         3 $inst ->{'destination'} = {};
33 1         4 return $inst;
34              
35             }
36             sub src {
37 1     1 1 758 my $self_inst = shift;
38 1 50       7 Carp::croak ("src can only be used by a VendorProof instance\n") if (! ref $self_inst eq 'CopyTree::VendorProof');
39 1         3 my $path = shift;
40 1         2 my $cp_inst =shift; #IMPORTANT: objects cannot be hash keys or it will be sringified
41 1         13 $self_inst -> {'source'}{$path}= $cp_inst;
42 1         6 return $self_inst;
43             }
44              
45              
46             sub dst {
47 7     7 1 28 my $self_inst = shift;
48 7 50       23 Carp::croak ("dst can only be used by a VendorProof instance\n") if (! ref $self_inst eq 'CopyTree::VendorProof');
49 7         9 my @keys = keys %{$self_inst ->{'destination'}};
  7         23  
50 7 100       17 if (@_){
51              
52 3         4 my $path = shift;
53 3         4 my $cp_inst =shift; #IMPORTANT: objects cannot be hash keys or it will be sringified
54 3 50       8 if (@keys){# We cannot use $self_inst ->{'destination'} , since even if it's an empty hash ref, it is defined.
55 0         0 Carp::croak ("you cannot have more than one destination. Previous destination is [".
56             #$self_inst ->{'destination'}{$keys[0]}. "]");
57             $keys[0]. "]");
58             }
59             #$keys[0]=$cp_inst;
60 3         7 $keys[0]=$path;
61 3         12 $self_inst -> {'destination'}{$keys[0]}=$cp_inst;
62             }
63             #returns the inst and the path
64             #else { return ($keys[0], $self_inst ->{'destination'}{$keys[0]}) }
65             else {
66 4 100       12 if ($keys[0]){
  2         300  
67              
68 2 50       7 if ($keys[0] ne ''){
  0         0  
69 2         8 return ($keys[0], $self_inst ->{'destination'}{$keys[0]});
70             }
71             else {Carp::croak("dest file is defined as '' (nothing)")}
72             }
73             else {Carp::croak("dest file is not defined.")}
74              
75             }
76              
77             }
78             sub cp{
79 3     3 1 14 my $inst=shift;
80 3         9 my ($destpath, $destinst) = $inst ->dst;
81 1 50 33     10 if (!$destpath or ! ref $destinst){
82 0         0 Carp::croak("no valid destination instance\n");#dest path error is handled in $inst->dst
83             }
84 1         15 my $desttype = $destinst->is_fd ($destpath) ;
85             #sanity check first, see if dest is a file and we have multi source or source that is dir
86 0           my $totsrc =keys %{ $inst ->{'source'} };
  0            
87              
88 0 0 0       if($totsrc >1 and $desttype eq 'f'){
89 0           Carp::croak("multi source and/or dir source cannot go into a file\n");
90             }
91 0           my @srcpaths = keys %{ $inst ->{'source'} };
  0            
92 0 0         Carp::croak("you don't have a source") if (! @srcpaths);
93              
94 0           for my $srcpath (@srcpaths ){
95 0           my $srcinst = $inst ->{'source'} ->{$srcpath};
96 0           my $srctype = $srcinst -> is_fd($srcpath);
97             #############D to D copy###############
98 0 0         if ($srctype eq 'd'){
    0          
99 0 0         if ($desttype ne 'd'){
100 0           Carp::croak("you cannot copy a dir [$srcpath] into a non / non-existing dir [$destpath]\n");
101             }
102 0           my $srcbasedir = $srcpath;
103 0           $srcbasedir =~s/.+\///; #takes last dirname, no parent
104             # print $srcbasedir. "\n";
105 0           my $srctree_no_srcdir =$srcinst->ls_tree($srcpath);
106 0           $destinst-> cust_mkdir("$destpath/$srcbasedir"); #creates source dir under dest dir
107 0           my ($files, $dirs) = $destinst ->ls_tree_fdret("", $srctree_no_srcdir);
108             # print Dumper $files; #/dwsfolder/new folder/1anovaSigNoMTC.with anno.csv',
109             # print Dumper $dirs; #'/dwsfolder/new folder',
110 0           $destinst ->cust_mkdir("$destpath/$srcbasedir$_") for @$dirs;
111 0           $inst ->copy_meth_deci($srcinst, $destinst, $srcpath, "$destpath/$srcbasedir", $_) for @$files;
112              
113             } #end if $srctype eq 'd'
114             ##############F to F / D copy#############
115             elsif ($srctype eq 'f'){
116             #file to file copy, file exists, overwrite with destpath.
117 0 0 0       if ($desttype eq 'f' or $desttype eq 'pd'){
    0          
118 0 0         print ("overwriting $destpath with $srcpath \n") if ($desttype eq 'f');
119 0           $inst ->copy_meth_deci($srcinst, $destinst, $srcpath, $destpath,'' );
120              
121             }
122             #file to dir copy, create source's basename under dest
123             elsif ($desttype eq 'd'){
124 0           my $source_no_parent = $srcpath;
125 0           $source_no_parent =~s/.+\///; #deletes dir part of path, leaving only filename
126 0           $inst-> copy_meth_deci($srcinst, $destinst, $srcpath, "$destpath/$source_no_parent", '');
127             }
128              
129             else {
130 0           Carp::carp ("destination type unclear [$desttype] for $destpath\n");
131             }
132              
133             }
134             else{
135 0           Carp::carp ("source file [$srcpath] does not exist\n");
136             }
137              
138             } #for my $srcinst
139              
140             }
141             #evaluates source inst and dest inst, if same, use local copy meths, if diff, use remote copy meths
142             #this reduces network traffic
143             sub copy_meth_deci{
144 0     0 1   my $cp_inst =shift;
145 0           my $srcinst=shift;
146 0           my $destinst=shift;
147 0           my $srcpath=shift;
148 0           my $destpath_basedir=shift;
149 0           my $filefromfiles=shift;
150 0 0         if ((ref $destinst) ne (ref $srcinst)){
151 0           $destinst ->write_from_memory($srcinst ->read_into_memory("$srcpath$filefromfiles") , "$destpath_basedir$filefromfiles");
152             }
153             #reduces network traffic
154             else{
155 0           $destinst->copy_local_files("$srcpath$filefromfiles", "$destpath_basedir$filefromfiles");
156             }
157              
158             }
159              
160             sub ls_tree{
161 0     0 1   my $class_inst = shift;
162 0           my $fullpath = shift; #this path is the full path
163            
164 0           my ($files,$dirs) = $class_inst->fdls( 'fdarrayrefs', $fullpath); #returns full path
165 0           my %structure;
166            
167             #starts inf loop of recursive case
168 0 0         if( @$dirs) {
169 0           for (@$dirs){
170 0           my $itemfullpath= $_;
171 0           s/^\Q$fullpath\E\/?// ;# $_ now carries no root path, and does not start with a slash
172 0           $structure{$_}=$class_inst->ls_tree($itemfullpath);
173             }
174             #DO NOT return, otherwise @$files will be omitted in the first level
175             }
176             #base case of no dirs under existing:
177             #DO NOT use else, becuase even with @$dirs, we still need to populate @$files
178             #if else is accidentally used, it only returns files at the last level
179 0           for (@$files){
180 0           s/^\Q$fullpath\E\/?// ;
181 0           $structure {$_} =undef;
182             }
183 0           return \%structure;
184              
185             }
186             sub path{
187 0     0 1   my $inst =shift;
188 0           my $path =shift;
189 0 0 0       if ($path and $path ne ''){ #and is lower precedence than &&
    0          
190 0           $inst ->{'path'} =$path;
191 0           return $inst;
192             }
193 0           elsif ($inst ->{'path'} ne ''){
194 0           return $inst ->{'path'};
195             }
196             else {Carp::croak("you must set a path through \$inst ->SUPER::path('someplace/something') to use this\n")}
197             }
198             sub fdls_ret{
199 0     0 1   my $inst = shift;
200 0           my $lsoption =shift;
201 0           my ($files, $dirs)=@_;
202 0           my @results;
203 0 0         if ($lsoption eq 'f'){
    0          
    0          
    0          
204 0           return @$files;
205             }
206             elsif ($lsoption eq 'd'){
207 0           return @$dirs;
208             }
209             elsif ($lsoption eq 'fdarrayrefs'){
210 0           return ($files, $dirs);
211             }
212 0           elsif ($lsoption eq ''){
213 0 0         push @results, @$files if (@$files);
214 0 0         push @results, @$dirs if (@$dirs);
215 0           return @results;
216             }
217             else {Carp::croak("wrong options: 'f', 'd', 'fdarrayrefs' allowable for lsoption\n")}
218              
219             }
220             sub ls_tree_fdret{
221 0     0 1   my $inst = shift;
222 0 0         Carp::croak("ls_tree_fdret item must be an instance, not a class\n") unless (ref $inst);
223 0           my $inst_root_path =shift;
224 0           my $hashref = shift;
225 0           my $files=shift; #this is only for the recursive action. no need for first call
226 0           my $dirs=shift;#this is only for the recursive action. no need for first call
227 0 0         $files =[] if (!ref $files);
228 0 0         $dirs =[] if (!ref $dirs);
229              
230 0           $inst_root_path =~s/\/$//; #removes trailing slashes, if any
231 0           for (keys %$hashref){
232 0 0         if (ref $hashref->{$_}){
233             # print "$_ is dir, gonna push $inst_root_path/$_\n";
234 0           push @$dirs, "$inst_root_path/$_";
235             #since we pass refs into the recursive structure, updates to $files and $dirs are automatically reflected
236 0           my ($newfiles, $newdirs)= $inst->ls_tree_fdret("$inst_root_path/$_", $hashref->{$_}, $files, $dirs);
237             }
238             else{
239             # print "$_ is file, gonna push $inst_root_path/$_\n";
240 0           push @$files, "$inst_root_path/$_";
241              
242             }
243             }#end for keys hashref
244 0           return ($files, $dirs);
245              
246             }
247              
248              
249              
250             # Autoload methods go after =cut, and are processed by the autosplit program.
251              
252             1;
253             __END__