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