line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package ShipIt::Util; |
2
|
2
|
|
|
2
|
|
8
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
64
|
|
3
|
2
|
|
|
2
|
|
12
|
use Carp qw(croak confess); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
246
|
|
4
|
|
|
|
|
|
|
require Exporter; |
5
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
6
|
|
|
|
|
|
|
our @EXPORT_OK = qw(slurp write_file bool_prompt edit_file $term make_var tempdir_obj |
7
|
|
|
|
|
|
|
find_subclasses in_dir); |
8
|
2
|
|
|
2
|
|
2006
|
use Term::ReadLine (); |
|
2
|
|
|
|
|
13299
|
|
|
2
|
|
|
|
|
44
|
|
9
|
2
|
|
|
2
|
|
3001
|
use File::Temp (); |
|
2
|
|
|
|
|
59178
|
|
|
2
|
|
|
|
|
63
|
|
10
|
2
|
|
|
2
|
|
17
|
use File::Path (); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
37
|
|
11
|
2
|
|
|
2
|
|
12
|
use Cwd; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
2138
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $term = eval { |
14
|
|
|
|
|
|
|
Term::ReadLine->new("prompt"); |
15
|
|
|
|
|
|
|
}; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub slurp { |
18
|
7
|
|
|
7
|
0
|
9
|
my ($file) = @_; |
19
|
7
|
50
|
|
|
|
321
|
open (my $fh, $file) or confess "Failed to open $file: $!\n"; |
20
|
7
|
|
|
|
|
12
|
return do { local $/; binmode $fh; <$fh>; } |
|
7
|
|
|
|
|
29
|
|
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
241
|
|
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub write_file { |
24
|
7
|
|
|
7
|
0
|
13
|
my ($file, $contents) = @_; |
25
|
7
|
50
|
|
|
|
568
|
open (my $fh, ">", $file) or confess "Failed to open $file for write: $!\n"; |
26
|
7
|
|
|
|
|
14
|
binmode $fh; |
27
|
7
|
|
|
|
|
30
|
print $fh $contents; |
28
|
7
|
50
|
|
|
|
221
|
close($fh) or confess "Close failed"; |
29
|
7
|
50
|
|
|
|
108
|
die "assert" unless -s $file == length($contents); |
30
|
7
|
|
|
|
|
33
|
return 1; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub bool_prompt { |
34
|
0
|
|
|
0
|
0
|
|
my ($q, $def) = @_; |
35
|
0
|
|
0
|
|
|
|
$def = uc($def || ""); |
36
|
0
|
0
|
|
|
|
|
die "bogus default" unless $def =~ /^[YN]?$/; |
37
|
0
|
0
|
|
|
|
|
return $def if !$term; |
38
|
0
|
|
|
|
|
|
my $opts = " [y/n]"; |
39
|
0
|
0
|
|
|
|
|
$opts = " [Y/n]" if $def eq "Y"; |
40
|
0
|
0
|
|
|
|
|
$opts = " [y/N]" if $def eq "N"; |
41
|
|
|
|
|
|
|
my $to_bool = sub { |
42
|
0
|
|
|
0
|
|
|
my $yn = shift; |
43
|
0
|
0
|
|
|
|
|
return 1 if $yn =~ /^y/i; |
44
|
0
|
0
|
|
|
|
|
return 0 if $yn =~ /^n/i; |
45
|
0
|
|
|
|
|
|
return undef; |
46
|
0
|
|
|
|
|
|
}; |
47
|
0
|
|
|
|
|
|
while (1) { |
48
|
0
|
|
|
|
|
|
my $ans = $term->readline("$q$opts "); |
49
|
0
|
|
0
|
|
|
|
my $bool = $to_bool->($ans || $def); |
50
|
0
|
0
|
|
|
|
|
return $bool if defined $bool; |
51
|
0
|
|
|
|
|
|
warn "Please answer 'y' or 'n'\n"; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub edit_file { |
56
|
0
|
|
|
0
|
0
|
|
my ($file) = @_; |
57
|
0
|
|
0
|
|
|
|
my $editor = $ENV{"EDITOR"} || "vi"; |
58
|
0
|
|
|
|
|
|
system($editor, $file); |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub make_var { |
62
|
0
|
|
|
0
|
0
|
|
my $var = shift; |
63
|
0
|
|
|
|
|
|
my $file = slurp("Makefile"); |
64
|
0
|
0
|
|
|
|
|
return undef unless $file =~ /^\Q$var\E\s*=\s*(.+)\s*/m; |
65
|
0
|
|
|
|
|
|
return $1; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub find_subclasses { |
69
|
|
|
|
|
|
|
# search for any other custom project type modules |
70
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
71
|
0
|
|
|
|
|
|
my @classes = (); |
72
|
0
|
|
|
|
|
|
for my $dir (@INC) { |
73
|
0
|
|
|
|
|
|
for my $file (glob("$dir/" . join("/", split(/::/, $class)) . "/*.pm")) { |
74
|
0
|
0
|
|
|
|
|
if($file =~ /\/(\w+)\.pm/) { |
75
|
0
|
|
|
|
|
|
push(@classes, "$class" . "::" . "$1"); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
} |
79
|
0
|
|
|
|
|
|
return @classes; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# returns either $obj or ($obj->dir, $obj), when in list context. |
83
|
|
|
|
|
|
|
# when $obj goes out of scope, all temp directory contents are wiped. |
84
|
|
|
|
|
|
|
sub tempdir_obj { |
85
|
0
|
0
|
|
0
|
0
|
|
my $dir = File::Temp::tempdir() or |
86
|
|
|
|
|
|
|
die "Failed to create temp directory: $!\n"; |
87
|
0
|
|
|
|
|
|
my $obj = bless { |
88
|
|
|
|
|
|
|
dir => $dir, |
89
|
|
|
|
|
|
|
}, "ShipIt::Util::TempDir"; |
90
|
0
|
0
|
|
|
|
|
return wantarray ? ($dir, $obj) : $obj; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# run a coderef in another directory, then return to old directory, |
94
|
|
|
|
|
|
|
# even if $code dies. |
95
|
|
|
|
|
|
|
sub in_dir { |
96
|
0
|
|
|
0
|
0
|
|
my ($dir, $code) = @_; |
97
|
0
|
|
|
|
|
|
my $old_cwd = getcwd; |
98
|
0
|
0
|
|
|
|
|
chdir($dir) or die "chdir to dir $dir failed: $!\n"; |
99
|
0
|
|
|
|
|
|
my $rv = eval { $code->(); }; |
|
0
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
my $err = $@; |
101
|
0
|
0
|
|
|
|
|
chdir($old_cwd) or die "chdir back to $old_cwd failed: $!\n"; |
102
|
0
|
0
|
|
|
|
|
die $err if $err; |
103
|
0
|
|
|
|
|
|
return $rv; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
############################################################################ |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
package ShipIt::Util::TempDir; |
110
|
0
|
|
|
0
|
|
|
sub directory { $_[0]{dir} }; |
111
|
|
|
|
|
|
|
sub DESTROY { |
112
|
0
|
|
|
0
|
|
|
my $self = shift; |
113
|
0
|
0
|
0
|
|
|
|
File::Path::rmtree($self->{dir}) if $self->{dir} && -d $self->{dir}; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
1; |