File Coverage

lib/Config/Proxy/Base.pm
Criterion Covered Total %
statement 81 127 63.7
branch 15 50 30.0
condition 0 3 0.0
subroutine 24 28 85.7
pod 0 13 0.0
total 120 221 54.3


line stmt bran cond sub pod time code
1             package Config::Proxy::Base;
2 7     7   3604 use 5.010;
  7         25  
3 7     7   73 use strict;
  7         15  
  7         174  
4 7     7   27 use warnings;
  7         10  
  7         459  
5 7     7   4009 use Text::Locus;
  7         29358  
  7         411  
6 7     7   3516 use Config::Proxy::Node::Root;
  7         28  
  7         261  
7 7     7   43 use Config::Proxy::Node::Section;
  7         11  
  7         150  
8 7     7   3258 use Config::Proxy::Node::Statement;
  7         37  
  7         335  
9 7     7   3272 use Config::Proxy::Node::Comment;
  7         23  
  7         361  
10 7     7   3030 use Config::Proxy::Node::Empty;
  7         23  
  7         245  
11 7     7   40 use File::Basename;
  7         13  
  7         677  
12 7     7   45 use File::Temp qw(tempfile);
  7         11  
  7         619  
13 7     7   4039 use File::stat;
  7         59610  
  7         573  
14 7     7   96 use File::Spec;
  7         13  
  7         287  
15 7     7   5397 use IPC::Cmd qw(run);
  7         476983  
  7         586  
16 7     7   70 use Carp;
  7         14  
  7         10349  
17              
18             sub new {
19 8     8 0 34 my ($class, $filename, $linter) = @_;
20 8         32 my $self = bless { _filename => $filename }, $class;
21 8 50       31 if ($linter) {
22 8         100 $self->{_lint} = { enable => 1, command => $linter };
23             } else {
24 0         0 $self->{_lint} = { enable => 0 }
25             }
26 8         48 $self->reset();
27 8         31 return $self;
28             }
29              
30 61     61 0 846 sub filename { shift->{_filename} }
31              
32             sub parse {
33 0     0 0 0 croak "not implemented"
34             }
35              
36             sub reset {
37 24     24 0 37 my $self = shift;
38 24         132 $self->{_tree} = new Config::Proxy::Node::Root();
39             }
40              
41 35     35 0 198 sub tree { shift->{_tree} }
42              
43             sub select {
44 6     6 0 3018 my $self = shift;
45 6         17 $self->tree->select(@_);
46             }
47              
48             sub iterator {
49 4     4 0 8 my $self = shift;
50 4         13 $self->tree->iterator(@_);
51             }
52              
53             sub write {
54 4     4 0 4195 my $self = shift;
55 4         13 $self->tree->write(@_)
56             }
57              
58             sub content {
59 1     1 0 13 my $self = shift;
60 1         2 my $s;
61 1 50       16 open(my $fh, '>', \$s) or croak "can't write to string: $!";
62 1         4 $self->write($fh);
63 1         4 close($fh);
64 1         29 return $s
65             }
66              
67             sub lint {
68 9     9 0 1179 my $self = shift;
69              
70 9 100       24 if (@_) {
71 4 100       16 if (@_ == 1) {
    50          
72 2         8 $self->{_lint}{enable} = !!shift;
73             } elsif (@_ % 2 == 0) {
74 2         9 local %_ = @_;
75 2         3 my $v;
76 2 50       7 if (defined($v = delete $_{enable})) {
77 2         6 $self->{_lint}{enable} = $v;
78             }
79 2 100       7 if (defined($v = delete $_{command})) {
80 1         3 $self->{_lint}{command} = $v;
81             }
82 2 50       6 if (defined($v = delete $_{path})) {
83 0         0 $self->{_lint}{path} = $v;
84             }
85 2 50       7 croak "unrecognized keywords" if keys %_;
86             } else {
87 0         0 croak "bad number of arguments";
88             }
89             }
90              
91 9 100       36 if ($self->{_lint}{enable}) {
92 5 50       14 if ($self->{_lint}{path}) {
93 0         0 my ($prog, $args) = split /\s+/, $self->{_lint}{command}, 2;
94 0 0       0 if (!File::Spec->file_name_is_absolute($prog)) {
95 0         0 foreach my $dir (split /:/, $self->{_lint}{path}) {
96 0         0 my $name = File::Spec->catfile($dir, $prog);
97 0 0       0 if (-x $name) {
98 0         0 $prog = $name;
99 0         0 last;
100             }
101             }
102 0 0       0 if ($args) {
103 0         0 $prog .= ' '.$args;
104             }
105 0         0 $self->{_lint}{command} = $prog;
106             }
107             }
108 5         20 return $self->{_lint}{command};
109             }
110             }
111              
112             sub save {
113 0     0 0   my $self = shift;
114 0 0         croak "bad number of arguments" if @_ % 2;
115 0           local %_ = @_;
116 0           my $dry_run = delete $_{dry_run};
117 0           my @wrargs = %_;
118              
119 0 0         return unless $self->tree;# FIXME
120 0 0         return unless $self->tree->is_dirty;
121 0           my ($fh, $tempfile) = tempfile('proxy.conf.XXXXXX',
122             DIR => dirname($self->filename));
123 0           $self->write($fh, @wrargs);
124 0           close($fh);
125 0 0         if (my $cmd = $self->lint) {
126 0           my ($ok, $err, $full, $outbuf, $errbuf) =
127             run(command => "$cmd $tempfile");
128 0 0         unless ($ok) {
129 0           unlink $tempfile;
130 0 0 0       if ($errbuf && @$errbuf) {
131 0           croak "Syntax check failed: ".join("\n", @$errbuf)."\n";
132             }
133 0           croak $err;
134             }
135             }
136 0 0         return 1 if $dry_run;
137              
138 0           my $sb = stat($self->filename);
139 0           $self->backup;
140 0 0         rename($tempfile, $self->filename)
141             or croak "can't rename $tempfile to ".$self->tempfile.": $!";
142              
143             # This will succeed: we've created the file, so we're owning it.
144 0           chmod $sb->mode & 0777, $self->filename;
145             # This will fail unless we are root, let it be so.
146 0           chown $sb->uid, $sb->gid, $self->filename;
147              
148 0           $self->tree->clear_dirty;
149 0           return 1;
150             }
151              
152             sub backup_name {
153 0     0 0   my $self = shift;
154 0           $self->filename . '~'
155             }
156              
157             sub backup {
158 0     0 0   my $self = shift;
159 0           my $backup = $self->backup_name;
160 0 0         if (-f $backup) {
161 0 0         unlink $backup
162             or croak "can't unlink $backup: $!"
163             }
164 0 0         rename $self->filename, $self->backup_name
165             or croak "can't rename :"
166             . $self->filename
167             . " to "
168             . $self->backup_name
169             . ": $!";
170             }
171              
172             1;