File Coverage

blib/lib/Dir/Project.pm
Criterion Covered Total %
statement 30 161 18.6
branch 0 50 0.0
condition 0 29 0.0
subroutine 10 27 37.0
pod 7 10 70.0
total 47 277 16.9


line stmt bran cond sub pod time code
1             # See copyright, etc in below POD section.
2             ######################################################################
3              
4             package Dir::Project;
5             require 5.005;
6             require Exporter;
7             @ISA = qw(Exporter);
8             @EXPORT = qw( $Project $HostDir );
9              
10 1     1   12863 use FindBin qw($RealBin);
  1         729  
  1         77  
11 1     1   6 use Carp;
  1         1  
  1         38  
12 1     1   4 use Cwd qw(abs_path getcwd);
  1         2  
  1         27  
13 1     1   5 use File::Basename;
  1         2  
  1         30  
14 1     1   4 use IO::File;
  1         2  
  1         75  
15 1     1   4 use IO::Handle;
  1         2  
  1         24  
16 1     1   341 use IO::Dir;
  1         8763  
  1         38  
17 1     1   367 use Sys::Hostname;
  1         732  
  1         41  
18              
19 1     1   6 use strict;
  1         2  
  1         20  
20 1     1   8 use vars qw($VERSION $Debug $Project %Env_Vars);
  1         2  
  1         1166  
21              
22             ######################################################################
23             #### Configuration Section
24              
25             $VERSION = '3.026';
26              
27             # List of all environment variables we might generate
28             %Env_Vars = (
29             DIRPROJECT => \&_get_project,
30             );
31              
32             ######################################################################
33             #### Begin
34              
35             ######################################################################
36             ######################################################################
37             ######################################################################
38             #### User callable
39              
40             sub default_script_dir {
41 0     0 0   return "$ENV{DIRPROJECT_PREFIX}/bin";
42             }
43              
44             sub get_set_project {
45 0     0 1   get_set_all();
46             }
47             sub get_set_all {
48             # This ordering matters
49             { # Compute temporary DIRPROJECT... We may end up changing the chip number,
50             # which will cause DIRPROJECT to change.
51 0     0 1   local $ENV{DIRPROJECT};
  0            
52 0           _get_set("DIRPROJECT");
53             }
54             # Project may have changed, make sure by recomputing
55 0           _get_set("DIRPROJECT");
56             # DIRPROJECT now correct
57 0           foreach (sort (keys %Env_Vars)) {
58 0 0 0       print "$_ = ",($ENV{$_}||''),"\n" if $Debug && $Debug > 1;
      0        
59             }
60             }
61              
62             ######################################################################
63             ######################################################################
64             ######################################################################
65             #### File utilities
66              
67             sub simplify_dirnames {
68 0     0 0   my $file = shift;
69 0 0         return undef if !defined $file;
70             #$file =~ s!^/nfs/remote/home!/home!;
71 0           return $file;
72             }
73              
74             sub program_paths {
75 0     0 1   my %params = (#program => # Name of program without path
76             #default_exe => # Name of default program if not found
77             @_);
78 0   0       $params{default_exe} ||= Dir::Project::default_script_dir()."/$params{program}__notfound";
79              
80 0           my @paths;
81 0   0       my $path = ($ENV{DIRPROJECT_PATH}||"");
82 0           foreach my $ppath (split (':', $path)) {
83 0           my $try = $ppath."/".$params{program};
84 0 0         if ($try =~ m!^project/!) { # Else we allow absolute paths also
85 0 0         next if !defined $Project;
86 0           $try =~ s!^project!$Project!;
87             }
88 0           push @paths, $try;
89             }
90 0           push @paths, $params{default_exe};
91              
92 0           return @paths;
93             }
94              
95             sub program_bin {
96 0     0 1   my %params = (paths=>[], # From program_paths
97             @_);
98              
99 0           foreach my $ppath (@{$params{paths}}) {
  0            
100 0 0         if (-r $ppath) {
101 0           return $ppath;
102             }
103             }
104 0           return undef;
105             }
106              
107             ######################################################################
108             ######################################################################
109             ######################################################################
110             #### Makefile
111              
112             sub makefile_path {
113 0   0 0 0   return ($ENV{TEMP}||$ENV{TMP}||"/tmp")."/project_dir";
114             }
115              
116             sub _makefile_lines {
117 0     0     my $fh = shift;
118              
119 0           foreach (sort (keys %Env_Vars)) {
120 0           my $val = $ENV{$_};
121 0 0         $val = "%Error_".$_."_not_found" if (!defined $val);
122 0           print $fh "$_ = $val\n";
123             }
124 0           print $fh "\n";
125 0           foreach (sort (keys %Env_Vars)) {
126 0           print $fh "export $_\n";
127             }
128             }
129              
130             sub makefile {
131             # Produce a makefile that will be included by project_bin.mk
132              
133 0     0 1   my $umask = umask();
134 0           umask 0;
135              
136 0           get_set_all();
137              
138 0           my $makefile_path = makefile_path();
139 0           mkdir $makefile_path, 0777;
140 0           _makefile_clean();
141 0           my $filename = "${makefile_path}/mktmp_$$";
142 0 0         my $fh = IO::File->new ($filename, ">", 0666) or die "%Error: $! $filename\n";
143              
144 0           print $fh "DIRPROJECT_MK_FILENAME = $filename\n";
145 0           _makefile_lines ($fh);
146 0           $fh->close();
147              
148             # Tell make to include this file
149 0           print "$filename\n";
150              
151 0           umask $umask;
152             }
153              
154             sub makefile_cat {
155 0     0 1   get_set_all();
156 0           my $fh = new IO::Handle;
157 0           $fh->fdopen(fileno(STDOUT),"w");
158 0           _makefile_lines ($fh);
159             }
160              
161             sub undefine_all {
162 0     0 1   foreach (keys %Env_Vars) {
163 0           delete $ENV{$_};
164             }
165             }
166              
167             sub _makefile_clean {
168             # See if we can clean up our clutter
169 0     0     my $clean_age = 600; # Seconds of time to leave them around
170              
171 0           my $now = time();
172              
173 0           my $makefile_path = makefile_path();
174 0 0         my $dir = new IO::Dir $makefile_path or return;
175 0           my $basefile;
176 0           while (defined($basefile = $dir->read)) {
177 0           my $file = "$makefile_path/$basefile";
178 0 0 0       next if ($file eq "." || $file eq "..");
179 0           my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime)
180             = stat($file);
181 0 0         if (($atime-$now) > $clean_age) {
182             #print "Cleaning tmp $file $atime $now ", $now - $atime, "\n" if $Debug;
183 0           unlink $file;
184             }
185             }
186             }
187              
188             ######################################################################
189             ######################################################################
190             ######################################################################
191             #### Setting each of the variables
192              
193             sub _get {
194 0     0     my $envvar = shift;
195             # Get the value for what would be the given environment variable
196             # without setting the environment at all
197 0 0         my $func = $Env_Vars{$envvar} or die "%Error: $envvar is unknown in Env_Vars";
198 0           my $value = &{$func};
  0            
199 0           return $value;
200             }
201              
202             sub _get_set {
203 0     0     my $envvar = shift;
204             # Get the value for the given environment variable
205             # and set it
206 0           my $value = _get($envvar);
207             #print "_get_set($envvar) = $value\n" if $Debug;
208 0 0         if (defined $value) {
209 0           $ENV{$envvar} = $value;
210             } else {
211 0           delete $ENV{$envvar};
212             }
213             }
214              
215             sub _get_project {
216             # Get the workarea/project pointer and set the DIRPROJECT environment variable
217 0     0     $Project = _get_root ("DIRPROJECT", 'project', undef);
218 0           return $Project;
219             }
220              
221             ######################################################################
222             ######################################################################
223             ######################################################################
224             #### Internals
225              
226             sub _get_root {
227 0     0     my $envvar = shift; # if $ENV{envvar}...
228 0           my $linkfile = shift; # if readlink $linkfile...
229 0           my $default = shift;
230             #
231              
232 0           my $value = undef;
233 0           my $comment = "undef";
234             search:
235 0           while (1) {
236 0 0         if (defined $ENV{$envvar}) {
237 0           $value = _resolve ($ENV{$envvar});
238 0           $comment = "set from environment $ENV{$envvar}";
239 0           last search;
240             }
241              
242             # Look for magic under cwd
243 0           my $cwd = getcwd();
244 0 0 0       print "_get_root: PWD=$cwd\n" if $Debug && $envvar eq "DIRPROJECT";
245 0           my $dir = $cwd."/.";
246 0           while ($dir =~ s/^(.*)\/.*$/$1/) {
247 0 0         last if $dir =~ m!/homes?/?$!; # Else automounter goes berserk
248 0 0         if (-r "$dir/Project_Root") {
249 0           $value = $dir;
250 0           $comment = "set from Project_Root under cwd";
251 0           last search;
252             }
253 0 0 0       if (-r "$dir/$linkfile" && readlink "$dir/$linkfile") {
254 0           $value = _resolve ("$dir/$linkfile");
255 0           $comment = "set from $dir/$linkfile link under cwd";
256 0           last search;
257             }
258             }
259              
260             # Look for magic under binary directory
261 0           $cwd = $RealBin;
262 0 0 0       print "_get_root: BINDIR=$cwd\n" if $Debug && $envvar eq "DIRPROJECT";
263 0           $dir = $cwd."/.";
264 0           while ($dir =~ s/^(.*)\/.*$/$1/) {
265 0 0         last if $dir =~ m!/homes?/?$!; # Else automounter goes berserk
266 0 0         if (-r "$dir/Project_Root") {
267 0           $value = $dir;
268 0           $comment = "set from Project_Root under bin dir";
269 0           last search;
270             }
271 0 0 0       if (-r "$dir/$linkfile" && readlink "$dir/$linkfile") {
272 0           $value = _resolve ("$dir/$linkfile");
273 0           $comment = "set from $dir/$linkfile link under bin dir";
274 0           last search;
275             }
276             }
277              
278 0 0         if (defined $default) {
279 0           $value = $default;
280 0           $comment = "default";
281 0           last search;
282             }
283              
284 0           last;
285             }
286              
287 0           $value = simplify_dirnames($value);
288              
289 0 0 0       print "_get_root: $envvar=",$value||'undef',"; $comment\n" if $Debug;
290 0           return ($value);
291             }
292              
293             sub _resolve {
294             # Rip apart any links in the path
295 0     0     my $file = shift;
296              
297 0           $file = abs_path($file);
298 0 0         return $file if ($file =~ /^\//);
299 0 0         if (readlink $file) {
300 0           $file = readlink $file;
301 0           $file = _resolve($file);
302             }
303 0           return $file;
304             }
305              
306             ######################################################################
307             ######################################################################
308             ######################################################################
309             #### Package return
310             1;
311              
312             __END__