File Coverage

blib/lib/App/Xssh.pm
Criterion Covered Total %
statement 69 95 72.6
branch 12 28 42.8
condition 2 8 25.0
subroutine 14 16 87.5
pod 5 5 100.0
total 102 152 67.1


line stmt bran cond sub pod time code
1             package App::Xssh;
2              
3 5     5   440199 use strict;
  5         61  
  5         147  
4 5     5   27 use warnings;
  5         8  
  5         144  
5              
6 5     5   58 use 5.6.0;
  5         18  
7              
8 5     5   2664 use Moose;
  5         2329766  
  5         38  
9 5     5   42144 use Getopt::Long;
  5         53599  
  5         26  
10 5     5   3695 use Pod::Usage;
  5         254641  
  5         711  
11 5     5   2849 use UNIVERSAL::require;
  5         5927  
  5         49  
12 5     5   2379 use App::Xssh::Config;
  5         21  
  5         78  
13 5     5   171 use version; our $VERSION = qv("v1.1.0");
  5         11  
  5         21  
14              
15             =head1 NAME
16              
17             App::Xssh - Encapsulates the application logic for xssh
18              
19             =head1 SYNOPSYS
20              
21             use App::Xssh;
22            
23             my $main = App::Xssh->new();
24             $main->run();
25             =cut
26              
27             =head1 METHODS
28              
29             =over
30              
31             =item new()
32              
33             Construcor, just used to provide an object with access to the methods
34              
35             =back
36              
37             =head1 METHODS
38              
39             =over
40              
41             =item upgradeConfig()
42              
43             Remove deprecation from the config data, if it changes anything it will
44             also write the config file back to disk.
45              
46             The deprecations are:
47              
48             =over
49              
50             =item *
51              
52             Rename the 'extra' attribute to 'profile' (since v0.5)
53              
54             =back
55             =cut
56             sub upgradeConfig {
57 5     5 1 1752 my ($self,$config,$data) = @_;
58              
59             my $rename = sub {
60 7     7   20 my ($name,$src,$dst) = @_;
61 7 100       45 if ( my $value = delete $name->{$src->[0]}->{$src->[1]}->{$src->[2]} ) {
62 2         7 $name->{$dst->[0]}->{$dst->[1]}->{$dst->[2]} = $value;
63 2         9 $config->add($dst,$value);
64 2         7 $config->delete($src);
65 2         7 $config->write();
66             }
67 5         31 };
68              
69             # Rename the 'extra' attribute to 'profile'
70 5         13 for my $host ( keys %{$data->{hosts} } ) {
  5         21  
71 6         29 $rename->($data,["hosts",$host,"extra"],["hosts",$host,"profile"]);
72             }
73 5 100       20 if ( $data->{extra} ) {
74 1         3 my $extra = $data->{extra};
75 1         4 for my $name ( keys %$extra ) {
76 1         3 for my $option ( keys %{$extra->{$name}} ) {
  1         3  
77 1         5 $rename->($data,["extra",$name,$option],["profile",$name,$option]);
78             }
79             }
80             }
81              
82 5         40 return $data;
83             }
84              
85             sub _mergeOptions {
86 9     9   27 my ($self,$data,$options,$moreOptions) = @_;
87              
88 9 100       30 if ( $moreOptions ) {
89 6         26 $options = { %$options, %$moreOptions };
90             }
91              
92 9         29 while ( my $value = delete $options->{profile} ) {
93 4         12 for my $profile ( split(/,/,$value) ) {
94 6 50       16 if ( my $details = $data->{profile}->{$profile} ) {
95 6         13 $options = { %$options, %{$data->{profile}->{$profile}} };
  6         35  
96             }
97             }
98             }
99              
100 9         24 return $options;
101             }
102              
103             =item getTerminalOptions()
104              
105             Reads the config data and determines the options that should be applied
106             for a given host
107             =cut
108             sub getTerminalOptions {
109 4     4 1 815 my ($self,$config,$host) = @_;
110              
111 4         16 my $data = $self->upgradeConfig($config,$config->read());
112              
113 4         10 my $options = {};
114              
115             # Begin with the DEFAULT options
116 4         16 $options = $self->_mergeOptions($data,$options,$data->{hosts}->{DEFAULT});
117              
118             # Add in any hosts that match
119 4         10 for my $hostmatch ( keys %{$data->{hosts}} ) {
  4         12  
120 5 100       69 if ( $host =~ m/^$hostmatch$/ ) {
121 3         15 $options = $self->_mergeOptions($data,$options,$data->{hosts}->{$hostmatch});
122             }
123             }
124              
125             # Finish with the specified host
126 4 100       16 if ( my $details = $data->{hosts}->{$host} ) {
127 2         18 $options = $self->_mergeOptions($data,$options,$data->{hosts}->{$host});
128             }
129              
130 4         10 $options->{host} = $host;
131 4         13 return($options);
132             }
133              
134             =item launchTerminal()
135              
136             Calls the X11::Terminal class to launch an X11 terminal emulator
137             =cut
138             sub launchTerminal {
139 0     0 1 0 my ($self,$options) = @_;
140              
141 0   0     0 my $type = $options->{type} || "XTerm";
142 0         0 my $class = "X11::Terminal::$type";
143 0 0       0 if ( $class->require ) {
144 0         0 my $term = $class->new(%$options);
145 0         0 return $term->launch();
146             }
147             }
148              
149             =item setValue()
150              
151             Sets a value in the config, and writes the config out
152             =cut
153             sub setValue {
154 4     4 1 1618 my ($self,$config,$category,$name,$option,$value) = @_;
155              
156 4 50 33     32 if ( ! ($name && $option && $value) ) {
      33        
157 0         0 pod2usage(1);
158             }
159              
160 4         20 $config->add([$category,$name,$option],$value);
161 4         13 return $config->write();
162             }
163              
164             =item run()
165              
166             This is the entry point for the xssh script. It parses the command line
167             and calls the appropraite application behaviour.
168              
169             =back
170             =cut
171             sub run {
172 0     0 1   my ($self) = @_;
173              
174 0           my $options = {};
175 0 0         GetOptions(
176             $options,
177             'sethostopt',
178             'setprofileopt',
179             'showconfig',
180             'version'
181             ) or pod2usage(1);
182            
183 0           my $config = App::Xssh::Config->new();
184 0 0         if ( $options->{sethostopt} ) {
185 0           $self->setValue($config,"hosts",@ARGV);
186 0           return 1;
187             }
188 0 0         if ( $options->{setprofileopt} ) {
189 0           $self->setValue($config,"profile",@ARGV);
190 0           return 1;
191             }
192 0 0         if ( $options->{showconfig} ) {
193 0           print $config->show($config);
194 0           return 1;
195             }
196 0 0         if ( $options->{version} ) {
197 0           print "Version: $VERSION\n";
198 0           return 1;
199             }
200              
201 0 0         if ( my ($host) = @ARGV ) {
202 0           my $options = $self->getTerminalOptions($config,$host);
203 0           return $self->launchTerminal($options);;
204             }
205             }
206              
207             =head1 COPYRIGHT & LICENSE
208              
209             Copyright 2010-2019 Evan Giles.
210              
211             This module is free software; you can redistribute it and/or modify it
212             under the same terms as Perl itself.
213             =cut
214              
215             1; # End of App::Xssh