File Coverage

blib/lib/App/Sqitch/Command/target.pm
Criterion Covered Total %
statement 143 143 100.0
branch 30 32 93.7
condition 10 10 100.0
subroutine 28 28 100.0
pod 8 8 100.0
total 219 221 99.1


line stmt bran cond sub pod time code
1              
2             use 5.010;
3 2     2   778 use strict;
  2         11  
4 2     2   18 use warnings;
  2         10  
  2         54  
5 2     2   11 use utf8;
  2         4  
  2         73  
6 2     2   14 use Moo;
  2         11  
  2         17  
7 2     2   42 use Types::Standard qw(Str Int HashRef);
  2         7  
  2         21  
8 2     2   961 use Locale::TextDomain qw(App-Sqitch);
  2         5  
  2         45  
9 2     2   2523 use App::Sqitch::X qw(hurl);
  2         5  
  2         30  
10 2     2   563 use URI::db;
  2         4  
  2         26  
11 2     2   1248 use Try::Tiny;
  2         15506  
  2         61  
12 2     2   14 use Path::Class qw(file dir);
  2         4  
  2         157  
13 2     2   14 use List::Util qw(max);
  2         4  
  2         142  
14 2     2   18 use namespace::autoclean;
  2         4  
  2         170  
15 2     2   17 use constant extra_target_keys => qw(uri);
  2         5  
  2         157  
16 2     2   192  
  2         4  
  2         3829  
17             extends 'App::Sqitch::Command';
18             with 'App::Sqitch::Role::TargetConfigCommand';
19              
20             our $VERSION = 'v1.3.1'; # VERSION
21              
22             # No config; target config is actually targets.
23             return {};
24             }
25              
26             my ( $self, $action ) = (shift, shift);
27             $action ||= 'list';
28             $action =~ s/-/_/g;
29 15     15 1 13918 my $meth = $self->can($action) or $self->usage(__x(
30 15   100     51 'Unknown action "{action}"',
31 15         29 action => $action,
32 15 100       67 ));
33             return $self->$meth(@_);
34             }
35              
36 14         41 my $self = shift;
37             my $sqitch = $self->sqitch;
38             my %targets = $sqitch->config->get_regexp(key => qr/^target[.][^.]+[.]uri$/);
39              
40 3     3 1 3155 # Make it verbose if --verbose was passed at all.
41 3         21 my $format = $sqitch->options->{verbosity} ? "%1\$s\t%2\$s" : '%1$s';
42 3         95 for my $key (sort keys %targets) {
43             my ($target) = $key =~ /target[.]([^.]+)/;
44             $sqitch->emit(sprintf $format, $target, $targets{$key});
45 3 100       813 }
46 3         24  
47 12         113 return $self;
48 12         90 }
49              
50             my ($self, $name, $uri) = @_;
51 3         41 $self->usage unless $name && $uri;
52              
53             my $key = "target.$name";
54             my $config = $self->sqitch->config;
55 8     8 1 12419  
56 8 100 100     94 hurl target => __x(
57             'Target "{target}" already exists',
58 6         46 target => $name
59 6         240 ) if $config->get( key => "$key.uri");
60              
61 6 100       119 # Put together the URI and other config variables.
62             my $vars = $self->config_params($key);
63             unshift @{ $vars } => {
64             key => "$key.uri",
65             value => URI::db->new($uri, 'db:')->as_string,
66             };
67 5         757  
68 5         15 # Make it so.
  5         82  
69             $config->group_set( $config->local_file, $vars );
70             my $target = $self->config_target(name => $name);
71             $self->write_plan(target => $target);
72             $self->make_directories_for( $target );
73             return $self;
74 5         1597 }
75 5         43568  
76 5         1277 my ($self, $target) = @_;
77 5         38 $self->usage unless $target;
78 5         151  
79             my $key = "target.$target";
80             my $config = $self->sqitch->config;
81             my $props = $self->properties;
82 5     5 1 8732  
83 5 100       38 hurl target => __x(
84             'Missing Target "{target}"; use "{command}" to add it',
85 4         18 target => $target,
86 4         172 command => "add $target " . ($props->{uri} || '$uri'),
87 4         69 ) unless $config->get( key => "target.$target.uri");
88              
89             # Make it so.
90             $config->group_set( $config->local_file, $self->config_params($key) );
91             $self->make_directories_for( $self->config_target(name => $target) );
92 4 100 100     32 }
93              
94             my ($self, $name) = @_;
95             $self->usage unless $name;
96 2         391 if ( my @deps = $self->_dependencies($name) ) {
97 2         41478 hurl target => __x(
98             q{Cannot rename target "{target}" because it's referenced by: {engines}},
99             target => $name,
100 2     2 1 8 engines => join ', ', @deps
101             );
102 5     5 1 6904 }
103 5 100       38 $self->_rename($name);
104 4 100       38 }
105 1         31  
106             my ($self, $old, $new) = @_;
107             $self->usage unless $old && $new;
108             if ( my @deps = $self->_dependencies($old) ) {
109             hurl target => __x(
110             q{Cannot rename target "{target}" because it's referenced by: {engines}},
111 3         30 target => $old,
112             engines => join ', ', @deps
113             );
114             }
115 6     6 1 54787 $self->_rename($old, $new);
116 6 100 100     81 }
117 4 100       26  
118 1         34 my ($self, $name) = @_;
119             my %depends = $self->sqitch->config->get_regexp(
120             key => qr/^(?:core|engine[.][^.]+)[.]target$/
121             );
122             return grep { $depends{$_} eq $name } sort keys %depends;
123             }
124 3         28  
125             my ($self, $old, $new) = @_;
126             my $config = $self->sqitch->config;
127              
128 8     8   30 try {
129 8         319 $config->rename_section(
130             from => "target.$old",
131             ($new ? (to => "target.$new") : ()),
132 8         1887 filename => $config->local_file,
  12         80  
133             );
134             } catch {
135             die $_ unless /No such section/;
136 6     6   25 hurl target => __x(
137 6         403 'Unknown target "{target}"',
138             target => $old,
139             );
140 6 100   6   678 };
141             try {
142             $config->rename_section(
143             from => "target.$old.variables",
144             ($new ? (to => "target.$new.variables") : ()),
145             filename => $config->local_file,
146 2 50   2   6813 );
147 2         37 } catch {
148             die $_ unless /No such section/;
149             };
150             return $self;
151 6         181 }
152              
153 4 100   4   303 my ($self, @names) = @_;
154             return $self->list unless @names;
155             my $sqitch = $self->sqitch;
156             my $config = $sqitch->config;
157              
158             my %label_for = (
159 2 50   2   6036 uri => __('URI'),
160 4         15862 registry => __('Registry'),
161 4         7657 client => __('Client'),
162             top_dir => __('Top Directory'),
163             plan_file => __('Plan File'),
164             extension => __('Extension'),
165 6     6 1 20317 revert => ' ' . __ 'Revert',
166 6 100       47 deploy => ' ' . __ 'Deploy',
167 5         24 verify => ' ' . __ 'Verify',
168 5         131 reworked => ' ' . __ 'Reworked',
169             );
170 5         58  
171             my $len = max map { length } values %label_for;
172             $_ .= ': ' . ' ' x ($len - length $_) for values %label_for;
173              
174             # Header labels.
175             $label_for{script_dirs} = __('Script Directories') . ':';
176             $label_for{reworked_dirs} = __('Reworked Script Directories') . ':';
177             $label_for{variables} = __('Variables') . ':';
178             $label_for{no_variables} = __('No Variables');
179              
180             require App::Sqitch::Target;
181             for my $name (@names) {
182             my $target = App::Sqitch::Target->new(
183 5         1197 $self->target_params,
  50         93  
184 5         68 name => $name,
185             );
186             $self->emit("* $name");
187 5         25 $self->emit(' ', $label_for{uri}, $target->uri->as_string);
188 5         152 $self->emit(' ', $label_for{registry}, $target->registry);
189 5         141 $self->emit(' ', $label_for{client}, $target->client);
190 5         133 $self->emit(' ', $label_for{top_dir}, $target->top_dir);
191             $self->emit(' ', $label_for{plan_file}, $target->plan_file);
192 5         152 $self->emit(' ', $label_for{extension}, $target->extension);
193 5         16 $self->emit(' ', $label_for{script_dirs});
194 7         136 $self->emit(' ', $label_for{deploy}, $target->deploy_dir);
195             $self->emit(' ', $label_for{revert}, $target->revert_dir);
196             $self->emit(' ', $label_for{verify}, $target->verify_dir);
197             $self->emit(' ', $label_for{reworked_dirs});
198 7         728 $self->emit(' ', $label_for{reworked}, $target->reworked_dir);
199 7         259 $self->emit(' ', $label_for{deploy}, $target->reworked_deploy_dir);
200 7         441 $self->emit(' ', $label_for{revert}, $target->reworked_revert_dir);
201 7         1086 $self->emit(' ', $label_for{verify}, $target->reworked_verify_dir);
202 7         984 my $vars = $target->variables;
203 7         2339 if (%{ $vars }) {
204 7         1676 my $len = max map { length } keys %{ $vars };
205 7         1860 $self->emit(' ', $label_for{variables});
206 7         268 $self->emit(" $_: " . (' ' x ($len - length $_)) . $vars->{$_})
207 7         1327 for sort { lc $a cmp lc $b } keys %{ $vars };
208 7         1180 } else {
209 7         1230 $self->emit(' ', $label_for{no_variables});
210 7         257 }
211 7         625 }
212 7         1243  
213 7         1329 return $self;
214 7         1255 }
215 7 100       151  
  7         16  
216 1         2 1;
  3         8  
  1         4  
217 1         21  
218              
219 1         29 =head1 Name
  2         34  
  1         15  
220              
221 6         96 App::Sqitch::Command::target - Add, modify, or list Sqitch target databases
222              
223             =head1 Synopsis
224              
225 5         335 my $cmd = App::Sqitch::Command::target->new(%params);
226             $cmd->execute;
227              
228             =head1 Description
229              
230             Manages Sqitch targets, which are stored in the local configuration file.
231              
232             =head1 Interface
233              
234             =head3 Class Methods
235              
236             =head3 C<extra_target_keys>
237              
238             Returns a list of additional option keys to be specified via options.
239              
240             =head2 Instance Methods
241              
242             =head2 Attributes
243              
244             =head3 C<properties>
245              
246             Hash of property values to set.
247              
248             =head3 C<verbose>
249              
250             Verbosity.
251              
252             =head3 C<execute>
253              
254             $target->execute($command);
255              
256             Executes the C<target> command.
257              
258             =head3 C<add>
259              
260             Implements the C<add> action.
261              
262             =head3 C<alter>
263              
264             Implements the C<alter> action.
265              
266             =head3 C<list>
267              
268             Implements the C<list> action.
269              
270             =head3 C<remove>
271              
272             =head3 C<rm>
273              
274             Implements the C<remove> action.
275              
276             =head3 C<rename>
277              
278             Implements the C<rename> action.
279              
280             =head3 C<show>
281              
282             Implements the C<show> action.
283              
284             =head1 See Also
285              
286             =over
287              
288             =item L<sqitch-target>
289              
290             Documentation for the C<target> command to the Sqitch command-line client.
291              
292             =item L<sqitch>
293              
294             The Sqitch command-line client.
295              
296             =back
297              
298             =head1 Author
299              
300             David E. Wheeler <david@justatheory.com>
301              
302             =head1 License
303              
304             Copyright (c) 2012-2022 iovation Inc., David E. Wheeler
305              
306             Permission is hereby granted, free of charge, to any person obtaining a copy
307             of this software and associated documentation files (the "Software"), to deal
308             in the Software without restriction, including without limitation the rights
309             to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
310             copies of the Software, and to permit persons to whom the Software is
311             furnished to do so, subject to the following conditions:
312              
313             The above copyright notice and this permission notice shall be included in all
314             copies or substantial portions of the Software.
315              
316             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
317             IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
318             FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
319             AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
320             LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
321             OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
322             SOFTWARE.
323              
324             =cut