File Coverage

blib/lib/Config/Identity.pm
Criterion Covered Total %
statement 77 84 91.6
branch 24 40 60.0
condition 7 11 63.6
subroutine 14 15 93.3
pod 1 9 11.1
total 123 159 77.3


line stmt bran cond sub pod time code
1             package Config::Identity;
2             # ABSTRACT: Load (and optionally decrypt via GnuPG) user/pass identity information
3             $Config::Identity::VERSION = '0.0018';
4              
5 1     1   1714479 use strict;
  1         3  
  1         39  
6 1     1   5 use warnings;
  1         1  
  1         36  
7              
8 1     1   6 use Carp;
  1         7  
  1         99  
9 1     1   429368 use IPC::Run qw/ start finish /;
  1         89817  
  1         67  
10 1     1   3166 use File::HomeDir();
  1         6608  
  1         26  
11 1     1   9 use File::Spec;
  1         1  
  1         10  
12              
13             our $home = File::HomeDir->home;
14             {
15             my $gpg;
16 4 50 66 4 0 1292 sub GPG() { $ENV{CI_GPG} || ( $gpg ||= do {
17 1         10 require File::Which;
18 1   50     7 $gpg = File::Which::which( $_ ) and last for qw/ gpg gpg2 /;
19 1         206 $gpg;
20             } ) }
21             }
22 3 50   3 0 17 sub GPG_ARGUMENTS() { $ENV{CI_GPG_ARGUMENTS} || '' }
23              
24             # TODO Do not even need to do this, since the file is on disk already...
25             sub decrypt {
26 3     3 0 9 my $self = shift;
27 3         7 my $file = shift;
28              
29 3 50       21 my $gpg = GPG or croak "Missing gpg";
30 3         16 my $gpg_arguments = GPG_ARGUMENTS;
31 3         5 my $run;
32             # Old versions, please ignore
33             #$run = "$gpg $gpg_arguments -qd --no-tty --command-fd 0 --status-fd 1";
34             #$run = "$gpg $gpg_arguments -qd --no-tty --command-fd 0";
35 3         15 $run = "$gpg $gpg_arguments -qd --no-tty";
36 3         25 my @run = split m/\s+/, $run;
37 3         7 push @run, $file;
38 3         27 my $process = start( \@run, '>pipe', \*OUT, '2>pipe', \*ERR );
39 3         141040 my $output = join '', ;
40 3         81 my $_error = join '', ;
41 3         54 finish $process;
42 3         3224 return ( $output, $_error );
43             }
44              
45             sub best {
46 6     6 0 275 my $self = shift;
47 6         19 my $stub = shift;
48 6         13 my $base = shift;
49 6 100       23 $base = $home unless defined $base;
50              
51 6 50 33     68 croak "Missing stub" unless defined $stub && length $stub;
52              
53 6         32 for my $i0 ( ".$stub-identity", ".$stub" ) {
54 9         16 for my $i1 ( "." ) {
55 9         80 my $path = File::Spec->catfile( $base, $i1, $i0 );
56 9 100       297 return $path if -f $path;
57             }
58             }
59              
60 0         0 return '';
61             }
62              
63             sub read {
64 5     5 0 33 my $self = shift;
65 5         8 my $file = shift;
66              
67 5 50       71 croak "Missing file" unless -f $file;
68 5 50       73 croak "Cannot read file ($file)" unless -r $file;
69              
70 5         29538 my $binary = -B $file;
71              
72 5 50       414 open my $handle, $file or croak $!;
73 5 100       21 binmode $handle if $binary;
74 5         29 local $/ = undef;
75 5         103 my $content = <$handle>;
76 5 50       67 close $handle or warn $!;
77              
78 5 100 100     62 if ( $binary || $content =~ m/----BEGIN PGP MESSAGE----/ ) {
79 3         53 my ( $_content, $error ) = $self->decrypt( $file );
80 3 50       424 if ( $error ) {
81 0 0       0 carp "Error during decryption of content" . $binary ? '' : "\n$content";
82 0         0 croak "Error during decryption of $file:\n$error";
83             }
84 3         25 $content = $_content;
85             }
86            
87 5         228 return $content;
88             }
89              
90             sub parse {
91 5     5 0 22 my $self = shift;
92 5         21 my $content = shift;
93              
94 5 50       18 return unless $content;
95 5         10 my %content;
96 5         24 for ( split m/\n/, $content ) {
97 13 100       59 next if /^\s*#/;
98 12 100       54 next unless m/\S/;
99 10 50       78 next unless my ($key, $value) = /^\s*(\w+)\s+(.+)$/;
100 10         40 $content{$key} = $value;
101             }
102 5         58 return %content;
103             }
104              
105             sub load_best {
106 0     0 1 0 my $self = shift;
107 0         0 my $stub = shift;
108              
109 0 0       0 die "Unable to find .$stub-identity or .$stub" unless my $path = $self->best( $stub );
110 0         0 return $self->load( $path );
111             }
112              
113             sub try_best {
114 4     4 0 15 my $self = shift;
115 4         9 my $stub = shift;
116              
117 4 50       19 return unless my $path = $self->best( $stub );
118 4         22 return $self->load( $path );
119             }
120              
121             sub load {
122 4     4 0 7 my $self = shift;
123 4         6 my $file = shift;
124              
125 4         15 return $self->parse( $self->read( $file ) );
126             }
127              
128             1;
129              
130             __END__