line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
use 5.010; |
3
|
50
|
|
|
50
|
|
1995
|
use strict; |
|
50
|
|
|
|
|
189
|
|
4
|
50
|
|
|
50
|
|
267
|
use warnings; |
|
50
|
|
|
|
|
84
|
|
|
50
|
|
|
|
|
1043
|
|
5
|
50
|
|
|
50
|
|
1142
|
use utf8; |
|
50
|
|
|
|
|
162
|
|
|
50
|
|
|
|
|
1506
|
|
6
|
50
|
|
|
50
|
|
292
|
use Try::Tiny; |
|
50
|
|
|
|
|
77
|
|
|
50
|
|
|
|
|
316
|
|
7
|
50
|
|
|
50
|
|
1197
|
use Locale::TextDomain qw(App-Sqitch); |
|
50
|
|
|
|
|
115
|
|
|
50
|
|
|
|
|
2962
|
|
8
|
50
|
|
|
50
|
|
311
|
use App::Sqitch::X qw(hurl); |
|
50
|
|
|
|
|
94
|
|
|
50
|
|
|
|
|
443
|
|
9
|
50
|
|
|
50
|
|
9493
|
use Hash::Merge 'merge'; |
|
50
|
|
|
|
|
98
|
|
|
50
|
|
|
|
|
562
|
|
10
|
50
|
|
|
50
|
|
14845
|
use File::Path qw(make_path); |
|
50
|
|
|
|
|
97
|
|
|
50
|
|
|
|
|
2655
|
|
11
|
50
|
|
|
50
|
|
299
|
use Moo; |
|
50
|
|
|
|
|
89
|
|
|
50
|
|
|
|
|
2148
|
|
12
|
50
|
|
|
50
|
|
269
|
use App::Sqitch::Types qw(Sqitch Target); |
|
50
|
|
|
|
|
76
|
|
|
50
|
|
|
|
|
385
|
|
13
|
50
|
|
|
50
|
|
18152
|
|
|
50
|
|
|
|
|
83
|
|
|
50
|
|
|
|
|
434
|
|
14
|
|
|
|
|
|
|
our $VERSION = 'v1.3.0'; # VERSION |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use constant ENGINES => qw( |
17
|
50
|
|
|
|
|
95777
|
pg |
18
|
|
|
|
|
|
|
sqlite |
19
|
|
|
|
|
|
|
mysql |
20
|
|
|
|
|
|
|
oracle |
21
|
|
|
|
|
|
|
firebird |
22
|
|
|
|
|
|
|
vertica |
23
|
|
|
|
|
|
|
exasol |
24
|
|
|
|
|
|
|
snowflake |
25
|
|
|
|
|
|
|
); |
26
|
50
|
|
|
50
|
|
35508
|
|
|
50
|
|
|
|
|
96
|
|
27
|
|
|
|
|
|
|
has sqitch => ( |
28
|
|
|
|
|
|
|
is => 'ro', |
29
|
|
|
|
|
|
|
isa => Sqitch, |
30
|
|
|
|
|
|
|
required => 1, |
31
|
|
|
|
|
|
|
handles => [qw( |
32
|
|
|
|
|
|
|
run |
33
|
|
|
|
|
|
|
shell |
34
|
|
|
|
|
|
|
quote_shell |
35
|
|
|
|
|
|
|
capture |
36
|
|
|
|
|
|
|
probe |
37
|
|
|
|
|
|
|
verbosity |
38
|
|
|
|
|
|
|
trace |
39
|
|
|
|
|
|
|
trace_literal |
40
|
|
|
|
|
|
|
debug |
41
|
|
|
|
|
|
|
debug_literal |
42
|
|
|
|
|
|
|
info |
43
|
|
|
|
|
|
|
info_literal |
44
|
|
|
|
|
|
|
comment |
45
|
|
|
|
|
|
|
comment_literal |
46
|
|
|
|
|
|
|
emit |
47
|
|
|
|
|
|
|
emit_literal |
48
|
|
|
|
|
|
|
vent |
49
|
|
|
|
|
|
|
vent_literal |
50
|
|
|
|
|
|
|
warn |
51
|
|
|
|
|
|
|
warn_literal |
52
|
|
|
|
|
|
|
page |
53
|
|
|
|
|
|
|
page_literal |
54
|
|
|
|
|
|
|
prompt |
55
|
|
|
|
|
|
|
ask_y_n |
56
|
|
|
|
|
|
|
)], |
57
|
|
|
|
|
|
|
); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
has default_target => ( |
60
|
|
|
|
|
|
|
is => 'ro', |
61
|
|
|
|
|
|
|
isa => Target, |
62
|
|
|
|
|
|
|
lazy => 1, |
63
|
|
|
|
|
|
|
default => sub { |
64
|
|
|
|
|
|
|
my $self = shift; |
65
|
|
|
|
|
|
|
my $sqitch = $self->sqitch; |
66
|
|
|
|
|
|
|
my @params = $self->target_params; |
67
|
|
|
|
|
|
|
unless ( |
68
|
|
|
|
|
|
|
$sqitch->config->get(key => 'core.engine') |
69
|
|
|
|
|
|
|
|| $sqitch->config->get(key => 'core.target') |
70
|
|
|
|
|
|
|
) { |
71
|
|
|
|
|
|
|
# No specified engine, so specify an engineless URI. |
72
|
|
|
|
|
|
|
require URI::db; |
73
|
|
|
|
|
|
|
unshift @params, uri => URI::db->new('db:'); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
require App::Sqitch::Target; |
76
|
|
|
|
|
|
|
return App::Sqitch::Target->new(@params); |
77
|
|
|
|
|
|
|
}, |
78
|
|
|
|
|
|
|
); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
my $class = ref $_[0] || shift; |
81
|
|
|
|
|
|
|
return '' if $class eq __PACKAGE__; |
82
|
256
|
|
66
|
256
|
1
|
19737
|
my $pkg = quotemeta __PACKAGE__; |
83
|
256
|
100
|
|
|
|
695
|
$class =~ s/^$pkg\:://; |
84
|
253
|
|
|
|
|
456
|
$class =~ s/_/-/g; |
85
|
253
|
|
|
|
|
1817
|
return $class; |
86
|
253
|
|
|
|
|
667
|
} |
87
|
253
|
|
|
|
|
1125
|
|
88
|
|
|
|
|
|
|
my ( $class, $sqitch, $cmd ) = @_; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
$cmd =~ s/-/_/g; |
91
|
65
|
|
|
65
|
1
|
1084
|
|
92
|
|
|
|
|
|
|
# Load the command class. |
93
|
65
|
|
|
|
|
200
|
my $pkg = __PACKAGE__ . "::$cmd"; |
94
|
|
|
|
|
|
|
eval "require $pkg; 1" or do { |
95
|
|
|
|
|
|
|
# Emit the original error for debugging. |
96
|
65
|
|
|
|
|
210
|
$sqitch->debug($@); |
97
|
65
|
100
|
|
|
|
3888
|
return undef; |
98
|
|
|
|
|
|
|
}; |
99
|
9
|
|
|
|
|
359
|
return $pkg; |
100
|
4
|
|
|
|
|
231
|
} |
101
|
|
|
|
|
|
|
|
102
|
56
|
|
|
|
|
359
|
my ( $class, $p ) = @_; |
103
|
|
|
|
|
|
|
# We should have a command. |
104
|
|
|
|
|
|
|
my $cmd = delete $p->{command} or $class->usage; |
105
|
|
|
|
|
|
|
my $pkg = $class->class_for($p->{sqitch}, $cmd) or hurl { |
106
|
39
|
|
|
39
|
1
|
52624
|
ident => 'command', |
107
|
|
|
|
|
|
|
exitval => 1, |
108
|
39
|
100
|
|
|
|
250
|
message => __x( |
109
|
38
|
100
|
|
|
|
187
|
'"{command}" is not a valid command', |
110
|
|
|
|
|
|
|
command => $cmd, |
111
|
|
|
|
|
|
|
), |
112
|
|
|
|
|
|
|
}; |
113
|
|
|
|
|
|
|
$pkg->create($p); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
117
|
35
|
|
|
|
|
255
|
|
118
|
|
|
|
|
|
|
# Merge the command-line options and configuration parameters |
119
|
|
|
|
|
|
|
my $params = $class->configure( |
120
|
|
|
|
|
|
|
$p->{config}, |
121
|
44
|
|
|
44
|
1
|
1243
|
$class->_parse_opts( $p->{args} ) |
122
|
|
|
|
|
|
|
); |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Instantiate and return the command. |
125
|
|
|
|
|
|
|
$params->{sqitch} = $p->{sqitch}; |
126
|
|
|
|
|
|
|
return $class->new($params); |
127
|
44
|
|
|
|
|
291
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
my ( $class, $config, $options ) = @_; |
130
|
44
|
|
|
|
|
2192
|
|
131
|
44
|
|
|
|
|
747
|
return Hash::Merge->new->merge( |
132
|
|
|
|
|
|
|
$options, |
133
|
|
|
|
|
|
|
$config->get_section( section => $class->command ), |
134
|
|
|
|
|
|
|
); |
135
|
93
|
|
|
93
|
1
|
21546
|
} |
136
|
|
|
|
|
|
|
|
137
|
93
|
|
|
|
|
566
|
return; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
my ( $class, $args ) = @_; |
141
|
|
|
|
|
|
|
return {} unless $args && @{$args}; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my %opts; |
144
|
7
|
|
|
7
|
1
|
50
|
Getopt::Long::Configure(qw(bundling no_pass_through)); |
145
|
|
|
|
|
|
|
Getopt::Long::GetOptionsFromArray( $args, \%opts, $class->options ) |
146
|
|
|
|
|
|
|
or $class->usage; |
147
|
|
|
|
|
|
|
|
148
|
49
|
|
|
49
|
|
3395
|
# Convert dashes to underscores. |
149
|
49
|
100
|
100
|
|
|
596
|
for my $k (keys %opts) { |
|
20
|
|
|
|
|
395
|
|
150
|
|
|
|
|
|
|
next unless ( my $nk = $k ) =~ s/-/_/g; |
151
|
16
|
|
|
|
|
31
|
$opts{$nk} = delete $opts{$k}; |
152
|
16
|
|
|
|
|
80
|
} |
153
|
16
|
100
|
|
|
|
910
|
|
154
|
|
|
|
|
|
|
return \%opts; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
16
|
|
|
|
|
5824
|
require File::Basename; |
158
|
10
|
100
|
|
|
|
54
|
File::Basename::basename($0); |
159
|
2
|
|
|
|
|
5
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
my ( $self, %params ) = @_; |
162
|
16
|
|
|
|
|
159
|
my $command = $self->command; |
163
|
|
|
|
|
|
|
require Pod::Find; |
164
|
|
|
|
|
|
|
require Pod::Usage; |
165
|
|
|
|
|
|
|
my $bn = _bn; |
166
|
11
|
|
|
11
|
|
33
|
my $find_pod = sub { |
167
|
11
|
|
|
|
|
388
|
Pod::Find::pod_where({ '-inc' => 1, '-script' => 1 }, shift ); |
168
|
|
|
|
|
|
|
}; |
169
|
|
|
|
|
|
|
$params{'-input'} ||= $find_pod->("$bn-$command") |
170
|
|
|
|
|
|
|
|| $find_pod->("sqitch-$command") |
171
|
8
|
|
|
8
|
|
41801
|
|| $find_pod->($bn) |
172
|
8
|
|
|
|
|
29
|
|| $find_pod->('sqitch') |
173
|
8
|
|
|
|
|
43
|
|| $find_pod->(ref $self || $self) |
174
|
8
|
|
|
|
|
28
|
|| $find_pod->(__PACKAGE__); |
175
|
8
|
|
|
|
|
23
|
Pod::Usage::pod2usage( |
176
|
|
|
|
|
|
|
'-verbose' => 99, |
177
|
26
|
|
|
26
|
|
18555
|
'-sections' => '(?i:(Usage|Synopsis|Options))', |
178
|
8
|
|
|
|
|
47
|
'-exitval' => 2, |
179
|
8
|
|
33
|
|
|
46
|
%params, |
|
|
|
66
|
|
|
|
|
180
|
|
|
|
|
|
|
); |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
my $self = shift; |
184
|
|
|
|
|
|
|
hurl( |
185
|
8
|
|
|
|
|
52
|
'The execute() method must be called from a subclass of ' |
186
|
|
|
|
|
|
|
. __PACKAGE__ |
187
|
|
|
|
|
|
|
) if ref $self eq __PACKAGE__; |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
hurl 'The execute() method has not been overridden in ' . ref $self; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
my $self = shift; |
193
|
|
|
|
|
|
|
require Pod::Find; |
194
|
2
|
|
|
2
|
1
|
81
|
my $upod = _bn . '-' . $self->command . '-usage'; |
195
|
2
|
100
|
|
|
|
12
|
$self->_pod2usage( |
196
|
|
|
|
|
|
|
'-input' => Pod::Find::pod_where( { '-inc' => 1 }, $upod ) || undef, |
197
|
|
|
|
|
|
|
'-message' => join '', @_ |
198
|
|
|
|
|
|
|
); |
199
|
|
|
|
|
|
|
} |
200
|
1
|
|
|
|
|
6
|
|
201
|
|
|
|
|
|
|
return (sqitch => shift->sqitch); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
3
|
|
|
3
|
1
|
80178
|
my ($self, %p) = @_; |
205
|
3
|
|
|
|
|
19
|
my $config = $self->sqitch->config; |
206
|
3
|
|
|
|
|
8
|
my @params = $self->target_params; |
207
|
3
|
|
50
|
|
|
2642
|
|
208
|
|
|
|
|
|
|
# Load the specified or default target. |
209
|
|
|
|
|
|
|
require App::Sqitch::Target; |
210
|
|
|
|
|
|
|
my $deftarget_err; |
211
|
|
|
|
|
|
|
my $target = try { |
212
|
|
|
|
|
|
|
App::Sqitch::Target->new( @params, name => $p{target} ) |
213
|
|
|
|
|
|
|
} catch { |
214
|
249
|
|
|
249
|
1
|
2328
|
# Die if a target was specified; otherwise keep the error for later. |
215
|
|
|
|
|
|
|
die $_ if $p{target}; |
216
|
|
|
|
|
|
|
$deftarget_err = $_; |
217
|
|
|
|
|
|
|
undef; |
218
|
177
|
|
|
177
|
1
|
40124
|
}; |
219
|
177
|
|
|
|
|
4642
|
|
220
|
177
|
|
|
|
|
3725
|
# Set up the default results. |
221
|
|
|
|
|
|
|
my (%seen, %target_for); |
222
|
|
|
|
|
|
|
my %rec = map { $_ => [] } qw(targets unknown); |
223
|
177
|
|
|
|
|
1660
|
$rec{changes} = [] unless $p{no_changes}; |
224
|
177
|
|
|
|
|
328
|
if ($p{target}) { |
225
|
|
|
|
|
|
|
push @{ $rec{targets} } => $target; |
226
|
|
|
|
|
|
|
$seen{$target->name}++; |
227
|
177
|
|
|
177
|
|
11611
|
} |
228
|
|
|
|
|
|
|
|
229
|
4
|
100
|
|
4
|
|
5226
|
# Iterate over the args to look for changes, engines, plans, or targets. |
230
|
3
|
|
|
|
|
6
|
my %engines = map { $_ => 1 } ENGINES; |
231
|
3
|
|
|
|
|
9
|
for my $arg (@{ $p{args} }) { |
232
|
177
|
|
|
|
|
1510
|
if ( !$p{no_changes} && $target && -e $target->plan_file && $target->plan->contains($arg) ) { |
233
|
|
|
|
|
|
|
# A change. |
234
|
|
|
|
|
|
|
push @{ $rec{changes} } => $arg; |
235
|
176
|
|
|
|
|
15597
|
} elsif ($config->get( key => "target.$arg.uri") || URI->new($arg)->isa('URI::db')) { |
236
|
176
|
|
|
|
|
384
|
# A target. Instantiate and keep for subsequente change searches. |
|
352
|
|
|
|
|
1105
|
|
237
|
176
|
100
|
|
|
|
708
|
$target = App::Sqitch::Target->new( @params, name => $arg ); |
238
|
176
|
100
|
|
|
|
461
|
push @{ $rec{targets} } => $target unless $seen{$target->name}++; |
239
|
44
|
|
|
|
|
100
|
} elsif ($engines{$arg}) { |
|
44
|
|
|
|
|
121
|
|
240
|
44
|
|
|
|
|
175
|
# An engine. Add its target. |
241
|
|
|
|
|
|
|
my $name = $config->get(key => "engine.$arg.target") || "db:$arg:"; |
242
|
|
|
|
|
|
|
$target = App::Sqitch::Target->new( @params, name => $name ); |
243
|
|
|
|
|
|
|
push @{ $rec{targets} } => $target unless $seen{$target->name}++; |
244
|
176
|
|
|
|
|
656
|
} elsif (-e $arg) { |
|
1408
|
|
|
|
|
2904
|
|
245
|
176
|
|
|
|
|
370
|
# Maybe it's a plan file? |
|
176
|
|
|
|
|
505
|
|
246
|
191
|
100
|
100
|
|
|
3711
|
%target_for = map { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
247
|
|
|
|
|
|
|
$_->plan_file => $_ |
248
|
47
|
|
|
|
|
69
|
} reverse App::Sqitch::Target->all_targets(@params) unless %target_for; |
|
47
|
|
|
|
|
211
|
|
249
|
|
|
|
|
|
|
if ($target_for{$arg}) { |
250
|
|
|
|
|
|
|
# It *is* a plan file. |
251
|
39
|
|
|
|
|
10030
|
$target = $target_for{$arg}; |
252
|
38
|
50
|
|
|
|
3117
|
push @{ $rec{targets} } => $target unless $seen{$target->name}++; |
|
38
|
|
|
|
|
649
|
|
253
|
|
|
|
|
|
|
} else { |
254
|
|
|
|
|
|
|
# Nah, who knows. |
255
|
21
|
|
66
|
|
|
3960
|
push @{ $rec{unknown} } => $arg; |
256
|
21
|
|
|
|
|
2799
|
} |
257
|
21
|
50
|
|
|
|
1692
|
} else { |
|
21
|
|
|
|
|
410
|
|
258
|
|
|
|
|
|
|
# Who knows? |
259
|
|
|
|
|
|
|
push @{ $rec{unknown} } => $arg; |
260
|
|
|
|
|
|
|
} |
261
|
7
|
50
|
|
|
|
1544
|
} |
|
14
|
|
|
|
|
2105
|
|
262
|
|
|
|
|
|
|
|
263
|
7
|
100
|
|
|
|
2426
|
# Replace missing names with unknown values. |
264
|
|
|
|
|
|
|
my @names = map { $_ || shift @{ $rec{unknown} } } @{ $p{names} || [] }; |
265
|
6
|
|
|
|
|
80
|
|
266
|
6
|
50
|
|
|
|
142
|
# Die on unknowns. |
|
6
|
|
|
|
|
238
|
|
267
|
|
|
|
|
|
|
if (my @unknown = @{ $rec{unknown} } ) { |
268
|
|
|
|
|
|
|
hurl $self->command => __nx( |
269
|
1
|
|
|
|
|
2
|
'Unknown argument "{arg}"', |
|
1
|
|
|
|
|
5
|
|
270
|
|
|
|
|
|
|
'Unknown arguments: {arg}', |
271
|
|
|
|
|
|
|
scalar @unknown, |
272
|
|
|
|
|
|
|
arg => join ', ', @unknown |
273
|
77
|
|
|
|
|
14497
|
); |
|
77
|
|
|
|
|
549
|
|
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# Figure out what targets to access. Use default unless --all. |
277
|
|
|
|
|
|
|
my @targets = @{ $rec{targets} }; |
278
|
175
|
100
|
|
|
|
932
|
if ($p{all}) { |
|
65
|
100
|
|
|
|
212
|
|
|
58
|
|
|
|
|
213
|
|
|
175
|
|
|
|
|
836
|
|
279
|
|
|
|
|
|
|
# Got --all. |
280
|
|
|
|
|
|
|
hurl $self->command => __( |
281
|
175
|
100
|
|
|
|
310
|
'Cannot specify both --all and engine, target, or plan arugments' |
|
175
|
|
|
|
|
580
|
|
282
|
21
|
|
|
|
|
115
|
) if @targets; |
283
|
|
|
|
|
|
|
@targets = App::Sqitch::Target->all_targets(@params ); |
284
|
|
|
|
|
|
|
} elsif (!@targets) { |
285
|
|
|
|
|
|
|
# Use all if tag.all is set, otherwise just the default. |
286
|
|
|
|
|
|
|
my $key = $self->command . '.all'; |
287
|
|
|
|
|
|
|
@targets = $self->sqitch->config->get(key => $key, as => 'bool') |
288
|
|
|
|
|
|
|
? App::Sqitch::Target->all_targets(@params ) |
289
|
|
|
|
|
|
|
: do { |
290
|
|
|
|
|
|
|
# Fall back on the default unless it's invalid. |
291
|
154
|
|
|
|
|
267
|
die $deftarget_err if $deftarget_err; |
|
154
|
|
|
|
|
316
|
|
292
|
154
|
100
|
|
|
|
565
|
($target) |
|
|
100
|
|
|
|
|
|
293
|
|
|
|
|
|
|
} |
294
|
12
|
100
|
|
|
|
77
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
return (@names, \@targets, $rec{changes}); |
297
|
8
|
|
|
|
|
74
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
my ( $self, $dir ) = @_; |
300
|
64
|
|
|
|
|
355
|
$self->debug( ' ', __x 'Created {file}', file => $dir ) |
301
|
|
|
|
|
|
|
if make_path $dir, { error => \my $err }; |
302
|
|
|
|
|
|
|
|
303
|
64
|
100
|
|
|
|
1390
|
my $diag = shift @{ $err } or return $self; |
304
|
|
|
|
|
|
|
|
305
|
60
|
100
|
|
|
|
7016
|
my ( $path, $msg ) = %{ $diag }; |
306
|
59
|
|
|
|
|
169
|
hurl $self->command => __x( |
307
|
|
|
|
|
|
|
'Error creating {path}: {error}', |
308
|
|
|
|
|
|
|
path => $path, |
309
|
|
|
|
|
|
|
error => $msg, |
310
|
149
|
|
|
|
|
1244
|
) if $path; |
311
|
|
|
|
|
|
|
hurl $self->command => $msg; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
162
|
|
|
162
|
|
84369
|
1; |
315
|
162
|
100
|
|
|
|
8368
|
|
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=head1 Name |
318
|
162
|
100
|
|
|
|
33937
|
|
|
162
|
|
|
|
|
673
|
|
319
|
|
|
|
|
|
|
App::Sqitch::Command - Sqitch Command support |
320
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
8
|
|
321
|
2
|
100
|
|
|
|
9
|
=head1 Synopsis |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
my $cmd = App::Sqitch::Command->load( deploy => \%params ); |
324
|
|
|
|
|
|
|
$cmd->run; |
325
|
|
|
|
|
|
|
|
326
|
1
|
|
|
|
|
6
|
=head1 Description |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
App::Sqitch::Command is the base class for all Sqitch commands. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head1 Interface |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=head2 Constants |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=head3 C<ENGINES> |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Returns the list of supported engines, currently: |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=over |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=item * C<firebird> |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=item * C<mysql> |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=item * C<oracle> |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=item * C<pg> |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=item * C<sqlite> |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=item * C<vertica> |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=item * C<exasol> |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=item * C<snowflake> |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=back |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=head2 Class Methods |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head3 C<options> |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
my @spec = App::Sqitch::Command->options; |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
Returns a list of L<Getopt::Long> options specifications. When C<load> loads |
365
|
|
|
|
|
|
|
the class, any options passed to the command will be parsed using these |
366
|
|
|
|
|
|
|
values. The keys in the resulting hash will be the first part of each option, |
367
|
|
|
|
|
|
|
with dashes converted to underscores. This hash will be passed to C<configure> |
368
|
|
|
|
|
|
|
along with a L<App::Sqitch::Config> object for munging into parameters to be |
369
|
|
|
|
|
|
|
passed to the constructor. |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Here's an example excerpted from the C<config> command: |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub options { |
374
|
|
|
|
|
|
|
return qw( |
375
|
|
|
|
|
|
|
get |
376
|
|
|
|
|
|
|
unset |
377
|
|
|
|
|
|
|
list |
378
|
|
|
|
|
|
|
global |
379
|
|
|
|
|
|
|
system |
380
|
|
|
|
|
|
|
config-file=s |
381
|
|
|
|
|
|
|
); |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
This will result in hash keys with the same names as each option except for |
385
|
|
|
|
|
|
|
C<config-file=s>, which will be named C<config_file>. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head3 C<configure> |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
my $params = App::Sqitch::Command->configure($config, $options); |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Takes two arguments, an L<App::Sqitch::Config> object and the hash of |
392
|
|
|
|
|
|
|
command-line options as specified by C<options>. The returned hash should be |
393
|
|
|
|
|
|
|
the result of munging these two objects into a hash reference of parameters to |
394
|
|
|
|
|
|
|
be passed to the command subclass constructor. |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
By default, this method converts dashes to underscores in command-line options |
397
|
|
|
|
|
|
|
keys, and then merges the configuration values with the options, with the |
398
|
|
|
|
|
|
|
command-line options taking priority. You may wish to override this method to |
399
|
|
|
|
|
|
|
do something different. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head3 C<class_for> |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
my $subclass = App::Sqitch::Command->subclass_for($sqitch, $cmd_name); |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
This method attempts to load the subclass of App::Sqitch::Commmand that |
406
|
|
|
|
|
|
|
corresponds to the command name. Returns C<undef> and sends errors to the |
407
|
|
|
|
|
|
|
C<debug> method of the <$sqitch> object if no such subclass can |
408
|
|
|
|
|
|
|
be loaded. |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=head2 Constructors |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
=head3 C<load> |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
my $cmd = App::Sqitch::Command->load( \%params ); |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
A factory method for instantiating Sqitch commands. It loads the subclass for |
417
|
|
|
|
|
|
|
the specified command and calls C<create> to instantiate and return an |
418
|
|
|
|
|
|
|
instance of the subclass. Sends error messages to the C<debug> method of the |
419
|
|
|
|
|
|
|
C<sqitch> parameter and throws an exception if the subclass does not exist or |
420
|
|
|
|
|
|
|
cannot be loaded. Supported parameters are: |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=over |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=item C<sqitch> |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
The App::Sqitch object driving the whole thing. |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=item C<config> |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
An L<App::Sqitch::Config> representing the current application configuration |
431
|
|
|
|
|
|
|
state. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=item C<command> |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
The name of the command to be executed. |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=item C<args> |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
An array reference of command-line arguments passed to the command. |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=back |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head3 C<create> |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
my $pkg = App::Sqitch::Command->class_for( $sqitch, $cmd_name ) |
446
|
|
|
|
|
|
|
or die "No such command $cmd_name"; |
447
|
|
|
|
|
|
|
my $cmd = $pkg->create({ |
448
|
|
|
|
|
|
|
sqitch => $sqitch, |
449
|
|
|
|
|
|
|
config => $config, |
450
|
|
|
|
|
|
|
args => \@ARGV, |
451
|
|
|
|
|
|
|
}); |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
Creates and returns a new object for a subclass of App::Sqitch::Command. It |
454
|
|
|
|
|
|
|
parses options from the C<args> parameter, calls C<configure> to merge |
455
|
|
|
|
|
|
|
configuration with the options, and finally calls C<new> with the resulting |
456
|
|
|
|
|
|
|
hash. Supported parameters are the same as for C<load> except for the |
457
|
|
|
|
|
|
|
C<command> parameter, which will be ignored. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head3 C<new> |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
my $cmd = App::Sqitch::Command->new(%params); |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
Instantiates and returns a App::Sqitch::Command object. This method is not |
464
|
|
|
|
|
|
|
designed to be overridden by subclasses; they should implement |
465
|
|
|
|
|
|
|
L<C<BUILDARGS>|Moo::Manual::Construction/BUILDARGS> or |
466
|
|
|
|
|
|
|
L<C<BUILD>|Moo::Manual::Construction/BUILD>, instead. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head2 Accessors |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=head3 C<sqitch> |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
my $sqitch = $cmd->sqitch; |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Returns the L<App::Sqitch> object that instantiated the command. Commands may |
475
|
|
|
|
|
|
|
access its properties in order to manage global state. |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=head2 Overridable Instance Methods |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
These methods should be overridden by all subclasses. |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=head3 C<execute> |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
$cmd->execute; |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Executes the command. This is the method that does the work of the command. |
486
|
|
|
|
|
|
|
Must be overridden in all subclasses. Dies if the method is not overridden for |
487
|
|
|
|
|
|
|
the object on which it is called, or if it is called against a base |
488
|
|
|
|
|
|
|
App::Sqitch::Command object. |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=head3 C<command> |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
my $command = $cmd->command; |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
The name of the command. Defaults to the last part of the package name, so as |
495
|
|
|
|
|
|
|
a rule you should not need to override it, since it is that string that Sqitch |
496
|
|
|
|
|
|
|
uses to find the command class. |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=head2 Utility Instance Methods |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
These methods are mainly provided as utilities for the command subclasses to |
501
|
|
|
|
|
|
|
use. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=head3 C<default_target> |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
my $target = $cmd->default_target; |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
This method returns the default target. It should only be used by commands |
508
|
|
|
|
|
|
|
that don't use a C<parse_args()> to find and load a target. |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
This method should always return a target option, never C<undef>. If the |
511
|
|
|
|
|
|
|
C<core.engine> configuration option has been set, then the target will support |
512
|
|
|
|
|
|
|
that engine. In the latter case, if C<engine.$engine.target> is set, that |
513
|
|
|
|
|
|
|
value will be used. Otherwise, the returned target will have a URI of C<db:> |
514
|
|
|
|
|
|
|
and no associated engine; the C<engine> method will throw an exception. This |
515
|
|
|
|
|
|
|
behavior should be fine for commands that don't need to load the engine. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=head3 C<parse_args> |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
my ($name1, $name2, $targets, $changes) = $cmd->parse_args( |
520
|
|
|
|
|
|
|
names => \@names, |
521
|
|
|
|
|
|
|
target => $target_name, |
522
|
|
|
|
|
|
|
args => \@args |
523
|
|
|
|
|
|
|
); |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Examines each argument to determine whether it's a known change spec or |
526
|
|
|
|
|
|
|
identifies a target or engine. Unrecognized arguments will replace false |
527
|
|
|
|
|
|
|
values in the C<names> array reference. Any remaining unknown arguments will |
528
|
|
|
|
|
|
|
trigger an error. |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Returns a list consisting all the desired names, followed by an array |
531
|
|
|
|
|
|
|
reference of target objects and an array reference of change specs. |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
This method is useful for commands that take a number of arguments where the |
534
|
|
|
|
|
|
|
order may be mixed. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
The supported parameters are: |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
=over |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=item C<args> |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
An array reference of the command arguments. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=item C<target> |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
The name of a target, if any. Useful for commands that offer their own |
547
|
|
|
|
|
|
|
C<--target> option. This target will be the default target, and the first |
548
|
|
|
|
|
|
|
returned in the targets array. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
=item C<names> |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
An array reference of names. If any is false, its place will be taken by an |
553
|
|
|
|
|
|
|
otherwise unrecognized argument. The number of values in this array reference |
554
|
|
|
|
|
|
|
determines the number of values returned as names in the return values. Such |
555
|
|
|
|
|
|
|
values may still be false or undefined; it's up to the caller to decide what |
556
|
|
|
|
|
|
|
to do about that. |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=item C<all> |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
In the event that no targets are recognized (or changes that implicitly |
561
|
|
|
|
|
|
|
recognize the default target), if this parameter is true, then all known |
562
|
|
|
|
|
|
|
targets from the configuration will be returned. |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=item C<no_changes> |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
If true, the parser will not check to see if any argument corresponds to a |
567
|
|
|
|
|
|
|
change. The last value returned will be C<undef> instead of the usual array |
568
|
|
|
|
|
|
|
reference. Any argument that might have been recognized as a change will |
569
|
|
|
|
|
|
|
instead be included in either the C<targets> array -- if it's recognized as a |
570
|
|
|
|
|
|
|
target -- or used to set names to return. Any remaining are considered |
571
|
|
|
|
|
|
|
unknown arguments and will result in an exception. |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=back |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
If a target parameter is passed, it will always be instantiated and returned |
576
|
|
|
|
|
|
|
as the first item in the "target" array, and arguments recognized as changes |
577
|
|
|
|
|
|
|
in the plan associated with that target will be returned as changes. |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
If no target is passed or appears in the arguments, a default target will be |
580
|
|
|
|
|
|
|
instantiated based on the command-line options and configuration. Unlike the |
581
|
|
|
|
|
|
|
target returned by C<default_target>, this target B<must> have an associated |
582
|
|
|
|
|
|
|
engine specified by the configuration. This is on the assumption that it will |
583
|
|
|
|
|
|
|
be used by commands that require an engine to do their work. Of course, any |
584
|
|
|
|
|
|
|
changes must be recognized from the plan associated with this target. |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Changes are only recognized if they're found in the plan of the target that |
587
|
|
|
|
|
|
|
precedes them. If no target precedes them, the target specified by the |
588
|
|
|
|
|
|
|
C<target> parameter or the default target will be searched. Such changes can |
589
|
|
|
|
|
|
|
be specified in any way documented in L<sqitchchanges>. |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
Targets may be recognized by any one of these types of arguments: |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=over |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=item * Target Name |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=item * Database URI |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=item * Engine Name |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=item * Plan File |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=back |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
In the case of plan files, C<parse_args()> will return the first target it |
606
|
|
|
|
|
|
|
finds for that plan file, even if multiple targets use the same plan file. The |
607
|
|
|
|
|
|
|
order of precedence for this determination is the default project target, |
608
|
|
|
|
|
|
|
followed by named targets, then engine targets. |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
=head3 C<target_params> |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
my $target = App::Sqitch::Target->new( $cmd->target_params ); |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
Returns a list of parameters suitable for passing to the C<new> or |
615
|
|
|
|
|
|
|
C<all_targets> constructors of App::Sqitch::Target. |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
=head3 C<run> |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
$cmd->run('echo hello'); |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
Runs a system command and waits for it to finish. Throws an exception on |
622
|
|
|
|
|
|
|
error. |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
=head3 C<capture> |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
my @files = $cmd->capture(qw(ls -lah)); |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
Runs a system command and captures its output to C<STDOUT>. Returns the output |
629
|
|
|
|
|
|
|
lines in list context and the concatenation of the lines in scalar context. |
630
|
|
|
|
|
|
|
Throws an exception on error. |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
=head3 C<probe> |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
my $git_version = $cmd->capture(qw(git --version)); |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
Like C<capture>, but returns just the C<chomp>ed first line of output. |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
=head3 C<verbosity> |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
my $verbosity = $cmd->verbosity; |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
Returns the verbosity level. |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head3 C<trace> |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
Send trace information to C<STDOUT> if the verbosity level is 3 or higher. |
647
|
|
|
|
|
|
|
Trace messages will have C<trace: > prefixed to every line. If it's lower than |
648
|
|
|
|
|
|
|
3, nothing will be output. |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
=head3 C<debug> |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
$cmd->debug('Found snuggle in the crib.'); |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
Send debug information to C<STDOUT> if the verbosity level is 2 or higher. |
655
|
|
|
|
|
|
|
Debug messages will have C<debug: > prefixed to every line. If it's lower than |
656
|
|
|
|
|
|
|
2, nothing will be output. |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
=head3 C<info> |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
$cmd->info('Nothing to deploy (up-to-date)'); |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Send informational message to C<STDOUT> if the verbosity level is 1 or higher, |
663
|
|
|
|
|
|
|
which, by default, it is. Should be used for normal messages the user would |
664
|
|
|
|
|
|
|
normally want to see. If verbosity is lower than 1, nothing will be output. |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=head3 C<comment> |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
$cmd->comment('On database flipr_test'); |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
Send comments to C<STDOUT> if the verbosity level is 1 or higher, which, by |
671
|
|
|
|
|
|
|
default, it is. Comments have C<# > prefixed to every line. If verbosity is |
672
|
|
|
|
|
|
|
lower than 1, nothing will be output. |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
=head3 C<emit> |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
$cmd->emit('core.editor=emacs'); |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
Send a message to C<STDOUT>, without regard to the verbosity. Should be used |
679
|
|
|
|
|
|
|
only if the user explicitly asks for output, such as for |
680
|
|
|
|
|
|
|
C<sqitch config --get core.editor>. |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=head3 C<vent> |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
$cmd->vent('That was a misage.'); |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
Send a message to C<STDERR>, without regard to the verbosity. Should be used |
687
|
|
|
|
|
|
|
only for error messages to be printed before exiting with an error, such as |
688
|
|
|
|
|
|
|
when reverting failed changes. |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=head3 C<page> |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
$sqitch->page('Search results:'); |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Like C<emit()>, but sends the output to a pager handle rather than C<STDOUT>. |
695
|
|
|
|
|
|
|
Unless there is no TTY (such as when output is being piped elsewhere), in |
696
|
|
|
|
|
|
|
which case it I<is> sent to C<STDOUT>. Meant to be used to send a lot of data |
697
|
|
|
|
|
|
|
to the user at once, such as when display the results of searching the event |
698
|
|
|
|
|
|
|
log: |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
$iter = $engine->search_events; |
701
|
|
|
|
|
|
|
while ( my $change = $iter->() ) { |
702
|
|
|
|
|
|
|
$cmd->page(join ' - ', @{ $change }{ qw(change_id event change) }); |
703
|
|
|
|
|
|
|
} |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
=head3 C<warn> |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
$cmd->warn('Could not find nerble; using nobble instead.'); |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
Send a warning messages to C<STDERR>. Warnings will have C<warning: > prefixed |
710
|
|
|
|
|
|
|
to every line. Use if something unexpected happened but you can recover from |
711
|
|
|
|
|
|
|
it. |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
=head3 C<usage> |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
$cmd->usage('Missing "value" argument'); |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
Sends the specified message to C<STDERR>, followed by the usage sections of |
718
|
|
|
|
|
|
|
the command's documentation. Those sections may be named "Name", "Synopsis", |
719
|
|
|
|
|
|
|
or "Options". Any or all of these will be shown. The doc used to display them |
720
|
|
|
|
|
|
|
will be the first found of: |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=over |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=item C<sqitch-$command-usage> |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=item C<sqitch-$command> |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=item C<sqitch> |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=item C<App::Sqitch::Command::$command> |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=item C<App::Sqitch::Command> |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=back |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
For an ideal usage messages, C<sqitch-$command-usage.pod> should be created by |
737
|
|
|
|
|
|
|
all command subclasses. |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
=head1 See Also |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=over |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
=item L<sqitch> |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
The Sqitch command-line client. |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
=back |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
=head1 Author |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
David E. Wheeler <david@justatheory.com> |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
=head1 License |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
Copyright (c) 2012-2022 iovation Inc., David E. Wheeler |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
758
|
|
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal |
759
|
|
|
|
|
|
|
in the Software without restriction, including without limitation the rights |
760
|
|
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
761
|
|
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is |
762
|
|
|
|
|
|
|
furnished to do so, subject to the following conditions: |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all |
765
|
|
|
|
|
|
|
copies or substantial portions of the Software. |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
768
|
|
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
769
|
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
770
|
|
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
771
|
|
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
772
|
|
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
773
|
|
|
|
|
|
|
SOFTWARE. |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
=cut |