File Coverage

blib/lib/App/Sqitch/Command/show.pm
Criterion Covered Total %
statement 64 64 100.0
branch 37 38 97.3
condition 2 3 66.6
subroutine 13 13 100.0
pod 1 1 100.0
total 117 119 98.3


line stmt bran cond sub pod time code
1             package App::Sqitch::Command::show;
2              
3 3     3   1867 use 5.010;
  3         26  
4 3     3   29 use strict;
  3         6  
  3         84  
5 3     3   22 use warnings;
  3         11  
  3         112  
6 3     3   20 use utf8;
  3         6  
  3         20  
7 3     3   113 use Locale::TextDomain qw(App-Sqitch);
  3         23  
  3         23  
8 3     3   672 use App::Sqitch::X qw(hurl);
  3         15  
  3         28  
9 3     3   1068 use List::Util qw(first);
  3         7  
  3         228  
10 3     3   24 use Moo;
  3         7  
  3         22  
11 3     3   1485 use App::Sqitch::Types qw(Bool Str);
  3         19  
  3         67  
12              
13             extends 'App::Sqitch::Command';
14             with 'App::Sqitch::Role::ContextCommand';
15              
16             our $VERSION = 'v1.4.0'; # VERSION
17              
18             has target => (
19             is => 'ro',
20             isa => Str,
21             );
22              
23             has exists_only => (
24             is => 'ro',
25             isa => Bool,
26             default => 0,
27             );
28              
29             sub options {
30             return qw(
31             target|t=s
32             exists|e!
33             );
34             }
35              
36             sub configure {
37             my ( $class, $config, $opt ) = @_;
38             $opt->{exists_only} = delete $opt->{exists}
39             if exists $opt->{exists};
40             return $class->SUPER::configure( $config, $opt );
41             }
42              
43             sub execute {
44 22     22 1 30181 my ( $self, $type, $key ) = @_;
45 22 100 66     103 $self->usage unless $type && $key;
46              
47 21         117 require App::Sqitch::Target;
48 21 100       494 my $target = $self->target ? App::Sqitch::Target->new(
49             $self->target_params,
50             name => $self->target,
51             ) : $self->default_target;
52 21         729 my $plan = $target->plan;
53              
54             # Handle tags first.
55 21 100       456 if ( $type eq 'tag' ) {
56 7         62 my $is_id = $key =~ /^[0-9a-f]{40}/;
57 7 100       45 my $change = $plan->get(
    100          
58             $is_id ? $key : ($key =~ /^@/ ? '' : '@') . $key
59             );
60              
61 7 100       20 my $tag = $change ? do {
62 4 100       18 if ($is_id) {
63             # It's a tag ID.
64 2     2   14 first { $_->id eq $key } $change->tags;
  2         57  
65             } else {
66             # Tag name.
67 2         16 (my $name = $key) =~ s/^[@]//;
68 2     2   16 first { $_->name eq $name } $change->tags;
  2         35  
69             }
70             } : undef;
71 7 100       37 unless ($tag) {
72 3 100       18 return if $self->exists_only;
73 2         12 hurl show => __x( 'Unknown tag "{tag}"', tag => $key );
74             }
75 4 100       64 $self->emit( $tag->info ) unless $self->exists_only;
76 4         182 return $self;
77             }
78              
79             # Make sure we recognize the type.
80             hurl show => __x(
81             'Unknown object type "{type}',
82             type => $type,
83 14 100   27   101 ) unless first { $type eq $_ } qw(change deploy revert verify);
  27         76  
84              
85             # Make sure we have a change object.
86 13 100       65 my $change = $plan->get($key) or do {
87 2 100       19 return if $self->exists_only;
88 1         8 hurl show => __x(
89             'Unknown change "{change}"',
90             change => $key
91             );
92             };
93              
94 11 100       30 if ($type eq 'change') {
95             # Just show its info.
96 6 100       105 $self->emit( $change->info ) unless $self->exists_only;
97 6         471 return $self;
98             }
99              
100 5         27 my $meth = $change->can("$type\_file");
101 5         23 my $path = $change->$meth;
102 5 100       512 unless (-e $path) {
103 2 100       105 return if $self->exists_only;
104 1         7 hurl show => __x('File "{path}" does not exist', path => $path);
105             }
106 3 50       172 hurl show => __x('"{path}" is not a file', path => $path)
107             if $path->is_dir;
108              
109 3 100       33 return $self if $self->exists_only;
110              
111             # Assume nothing about the encoding.
112 2         15 binmode STDOUT, ':raw';
113 2         9 $self->emit( $path->slurp(iomode => '<:raw') );
114 2         617 return $self;
115             }
116              
117             1;
118              
119             __END__
120              
121             =head1 Name
122              
123             App::Sqitch::Command::show - Show Sqitch changes to a database
124              
125             =head1 Synopsis
126              
127             my $cmd = App::Sqitch::Command::show->new(%params);
128             $cmd->execute($type, $name);
129              
130             =head1 Description
131              
132             Shows the content of a Sqitch object.
133              
134             If you want to know how to use the C<show> command, you probably want to be
135             reading C<sqitch-show>. But if you really want to know how the C<show> command
136             works, read on.
137              
138             =head1 Interface
139              
140             =head2 Class Methods
141              
142             =head3 C<options>
143              
144             my @opts = App::Sqitch::Command::show->options;
145              
146             Returns a list of L<Getopt::Long> option specifications for the command-line
147             options for the C<show> command.
148              
149             =head2 Attributes
150              
151             =head3 C<exists_only>
152              
153             Boolean indicating whether or not to suppress output and instead exit with
154             zero status if object exists and is a valid object.
155              
156             =head2 Instance Methods
157              
158             =head3 C<execute>
159              
160             $show->execute;
161              
162             Executes the show command.
163              
164             =head1 See Also
165              
166             =over
167              
168             =item L<sqitch-show>
169              
170             Documentation for the C<show> command to the Sqitch command-line client.
171              
172             =item L<sqitch>
173              
174             The Sqitch command-line client.
175              
176             =back
177              
178             =head1 Author
179              
180             David E. Wheeler <david@justatheory.com>
181              
182             =head1 License
183              
184             Copyright (c) 2012-2023 iovation Inc., David E. Wheeler
185              
186             Permission is hereby granted, free of charge, to any person obtaining a copy
187             of this software and associated documentation files (the "Software"), to deal
188             in the Software without restriction, including without limitation the rights
189             to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
190             copies of the Software, and to permit persons to whom the Software is
191             furnished to do so, subject to the following conditions:
192              
193             The above copyright notice and this permission notice shall be included in all
194             copies or substantial portions of the Software.
195              
196             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
197             IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198             FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
199             AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
200             LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
201             OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
202             SOFTWARE.
203              
204             =cut