Merge lp:~percona-toolkit-dev/percona-toolkit/fix-option-parser-bug-1199589-2.1 into lp:percona-toolkit/2.1

Proposed by Daniel Nichter
Status: Superseded
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-option-parser-bug-1199589-2.1
Merge into: lp:percona-toolkit/2.1
Diff against target: 2615 lines (+1601/-86)
31 files modified
bin/pt-archiver (+51/-1)
bin/pt-config-diff (+51/-1)
bin/pt-deadlock-logger (+51/-1)
bin/pt-diskstats (+51/-1)
bin/pt-duplicate-key-checker (+51/-1)
bin/pt-fifo-split (+51/-1)
bin/pt-find (+51/-1)
bin/pt-fingerprint (+51/-1)
bin/pt-fk-error-logger (+51/-1)
bin/pt-heartbeat (+51/-1)
bin/pt-index-usage (+51/-1)
bin/pt-kill (+51/-1)
bin/pt-log-player (+51/-1)
bin/pt-online-schema-change (+51/-1)
bin/pt-query-advisor (+51/-1)
bin/pt-query-digest (+51/-1)
bin/pt-show-grants (+51/-1)
bin/pt-slave-delay (+51/-1)
bin/pt-slave-find (+51/-1)
bin/pt-slave-restart (+51/-1)
bin/pt-table-checksum (+51/-1)
bin/pt-table-sync (+51/-1)
bin/pt-table-usage (+57/-10)
bin/pt-tcp-model (+51/-1)
bin/pt-trend (+51/-1)
bin/pt-upgrade (+51/-1)
bin/pt-variable-advisor (+51/-1)
bin/pt-visual-explain (+57/-10)
lib/OptionParser.pm (+52/-40)
t/lib/OptionParser.t (+53/-0)
t/pt-archiver/bugs.t (+56/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-option-parser-bug-1199589-2.1
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+180024@code.launchpad.net

This proposal has been superseded by a proposal from 2013-08-14.

To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Unmerged revisions

544. By Daniel Nichter

Apply t/pt-archiver/bugs.t.

543. By Daniel Nichter

Update OptionParser in all tools.

542. By Daniel Nichter

Apply fixed OptionParser.pm and tests.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-archiver'
2--- bin/pt-archiver 2013-07-18 17:31:04 +0000
3+++ bin/pt-archiver 2013-08-14 00:47:54 +0000
4@@ -65,6 +65,7 @@
5
6 use List::Util qw(max);
7 use Getopt::Long;
8+use Data::Dumper;
9
10 my $POD_link_re = '[LC]<"?([^">]+)"?>';
11
12@@ -460,11 +461,21 @@
13 my $long = exists $self->{opts}->{$opt} ? $opt
14 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
15 : die "Getopt::Long gave a nonexistent option: $opt";
16-
17 $opt = $self->{opts}->{$long};
18 if ( $opt->{is_cumulative} ) {
19 $opt->{value}++;
20 }
21+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
22+ my $next_opt = $1;
23+ if ( exists $self->{opts}->{$next_opt}
24+ || exists $self->{short_opts}->{$next_opt} ) {
25+ $self->save_error("--$long requires a string value");
26+ return;
27+ }
28+ else {
29+ $opt->{value} = $val;
30+ }
31+ }
32 else {
33 $opt->{value} = $val;
34 }
35@@ -1048,6 +1059,45 @@
36 );
37 };
38
39+sub set_vars {
40+ my ($self, $file) = @_;
41+ $file ||= $self->{file} || __FILE__;
42+
43+ my %user_vars;
44+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
45+ if ( $user_vars ) {
46+ foreach my $var_val ( @$user_vars ) {
47+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
48+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
49+ $user_vars{$var} = {
50+ val => $val,
51+ default => 0,
52+ };
53+ }
54+ }
55+
56+ my %default_vars;
57+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
58+ if ( $default_vars ) {
59+ %default_vars = map {
60+ my $var_val = $_;
61+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
62+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
63+ $var => {
64+ val => $val,
65+ default => 1,
66+ };
67+ } split("\n", $default_vars);
68+ }
69+
70+ my %vars = (
71+ %default_vars, # first the tool's defaults
72+ %user_vars, # then the user's which overwrite the defaults
73+ );
74+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
75+ return \%vars;
76+}
77+
78 sub _d {
79 my ($package, undef, $line) = caller 0;
80 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
81
82=== modified file 'bin/pt-config-diff'
83--- bin/pt-config-diff 2013-07-18 17:31:04 +0000
84+++ bin/pt-config-diff 2013-08-14 00:47:54 +0000
85@@ -64,6 +64,7 @@
86
87 use List::Util qw(max);
88 use Getopt::Long;
89+use Data::Dumper;
90
91 my $POD_link_re = '[LC]<"?([^">]+)"?>';
92
93@@ -459,11 +460,21 @@
94 my $long = exists $self->{opts}->{$opt} ? $opt
95 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
96 : die "Getopt::Long gave a nonexistent option: $opt";
97-
98 $opt = $self->{opts}->{$long};
99 if ( $opt->{is_cumulative} ) {
100 $opt->{value}++;
101 }
102+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
103+ my $next_opt = $1;
104+ if ( exists $self->{opts}->{$next_opt}
105+ || exists $self->{short_opts}->{$next_opt} ) {
106+ $self->save_error("--$long requires a string value");
107+ return;
108+ }
109+ else {
110+ $opt->{value} = $val;
111+ }
112+ }
113 else {
114 $opt->{value} = $val;
115 }
116@@ -1047,6 +1058,45 @@
117 );
118 };
119
120+sub set_vars {
121+ my ($self, $file) = @_;
122+ $file ||= $self->{file} || __FILE__;
123+
124+ my %user_vars;
125+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
126+ if ( $user_vars ) {
127+ foreach my $var_val ( @$user_vars ) {
128+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
129+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
130+ $user_vars{$var} = {
131+ val => $val,
132+ default => 0,
133+ };
134+ }
135+ }
136+
137+ my %default_vars;
138+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
139+ if ( $default_vars ) {
140+ %default_vars = map {
141+ my $var_val = $_;
142+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
143+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
144+ $var => {
145+ val => $val,
146+ default => 1,
147+ };
148+ } split("\n", $default_vars);
149+ }
150+
151+ my %vars = (
152+ %default_vars, # first the tool's defaults
153+ %user_vars, # then the user's which overwrite the defaults
154+ );
155+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
156+ return \%vars;
157+}
158+
159 sub _d {
160 my ($package, undef, $line) = caller 0;
161 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
162
163=== modified file 'bin/pt-deadlock-logger'
164--- bin/pt-deadlock-logger 2013-07-18 17:31:04 +0000
165+++ bin/pt-deadlock-logger 2013-08-14 00:47:54 +0000
166@@ -62,6 +62,7 @@
167
168 use List::Util qw(max);
169 use Getopt::Long;
170+use Data::Dumper;
171
172 my $POD_link_re = '[LC]<"?([^">]+)"?>';
173
174@@ -457,11 +458,21 @@
175 my $long = exists $self->{opts}->{$opt} ? $opt
176 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
177 : die "Getopt::Long gave a nonexistent option: $opt";
178-
179 $opt = $self->{opts}->{$long};
180 if ( $opt->{is_cumulative} ) {
181 $opt->{value}++;
182 }
183+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
184+ my $next_opt = $1;
185+ if ( exists $self->{opts}->{$next_opt}
186+ || exists $self->{short_opts}->{$next_opt} ) {
187+ $self->save_error("--$long requires a string value");
188+ return;
189+ }
190+ else {
191+ $opt->{value} = $val;
192+ }
193+ }
194 else {
195 $opt->{value} = $val;
196 }
197@@ -1045,6 +1056,45 @@
198 );
199 };
200
201+sub set_vars {
202+ my ($self, $file) = @_;
203+ $file ||= $self->{file} || __FILE__;
204+
205+ my %user_vars;
206+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
207+ if ( $user_vars ) {
208+ foreach my $var_val ( @$user_vars ) {
209+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
210+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
211+ $user_vars{$var} = {
212+ val => $val,
213+ default => 0,
214+ };
215+ }
216+ }
217+
218+ my %default_vars;
219+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
220+ if ( $default_vars ) {
221+ %default_vars = map {
222+ my $var_val = $_;
223+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
224+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
225+ $var => {
226+ val => $val,
227+ default => 1,
228+ };
229+ } split("\n", $default_vars);
230+ }
231+
232+ my %vars = (
233+ %default_vars, # first the tool's defaults
234+ %user_vars, # then the user's which overwrite the defaults
235+ );
236+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
237+ return \%vars;
238+}
239+
240 sub _d {
241 my ($package, undef, $line) = caller 0;
242 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
243
244=== modified file 'bin/pt-diskstats'
245--- bin/pt-diskstats 2013-07-18 17:31:04 +0000
246+++ bin/pt-diskstats 2013-08-14 00:47:54 +0000
247@@ -64,6 +64,7 @@
248
249 use List::Util qw(max);
250 use Getopt::Long;
251+use Data::Dumper;
252
253 my $POD_link_re = '[LC]<"?([^">]+)"?>';
254
255@@ -459,11 +460,21 @@
256 my $long = exists $self->{opts}->{$opt} ? $opt
257 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
258 : die "Getopt::Long gave a nonexistent option: $opt";
259-
260 $opt = $self->{opts}->{$long};
261 if ( $opt->{is_cumulative} ) {
262 $opt->{value}++;
263 }
264+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
265+ my $next_opt = $1;
266+ if ( exists $self->{opts}->{$next_opt}
267+ || exists $self->{short_opts}->{$next_opt} ) {
268+ $self->save_error("--$long requires a string value");
269+ return;
270+ }
271+ else {
272+ $opt->{value} = $val;
273+ }
274+ }
275 else {
276 $opt->{value} = $val;
277 }
278@@ -1047,6 +1058,45 @@
279 );
280 };
281
282+sub set_vars {
283+ my ($self, $file) = @_;
284+ $file ||= $self->{file} || __FILE__;
285+
286+ my %user_vars;
287+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
288+ if ( $user_vars ) {
289+ foreach my $var_val ( @$user_vars ) {
290+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
291+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
292+ $user_vars{$var} = {
293+ val => $val,
294+ default => 0,
295+ };
296+ }
297+ }
298+
299+ my %default_vars;
300+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
301+ if ( $default_vars ) {
302+ %default_vars = map {
303+ my $var_val = $_;
304+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
305+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
306+ $var => {
307+ val => $val,
308+ default => 1,
309+ };
310+ } split("\n", $default_vars);
311+ }
312+
313+ my %vars = (
314+ %default_vars, # first the tool's defaults
315+ %user_vars, # then the user's which overwrite the defaults
316+ );
317+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
318+ return \%vars;
319+}
320+
321 sub _d {
322 my ($package, undef, $line) = caller 0;
323 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
324
325=== modified file 'bin/pt-duplicate-key-checker'
326--- bin/pt-duplicate-key-checker 2013-07-18 17:31:04 +0000
327+++ bin/pt-duplicate-key-checker 2013-08-14 00:47:54 +0000
328@@ -979,6 +979,7 @@
329
330 use List::Util qw(max);
331 use Getopt::Long;
332+use Data::Dumper;
333
334 my $POD_link_re = '[LC]<"?([^">]+)"?>';
335
336@@ -1374,11 +1375,21 @@
337 my $long = exists $self->{opts}->{$opt} ? $opt
338 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
339 : die "Getopt::Long gave a nonexistent option: $opt";
340-
341 $opt = $self->{opts}->{$long};
342 if ( $opt->{is_cumulative} ) {
343 $opt->{value}++;
344 }
345+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
346+ my $next_opt = $1;
347+ if ( exists $self->{opts}->{$next_opt}
348+ || exists $self->{short_opts}->{$next_opt} ) {
349+ $self->save_error("--$long requires a string value");
350+ return;
351+ }
352+ else {
353+ $opt->{value} = $val;
354+ }
355+ }
356 else {
357 $opt->{value} = $val;
358 }
359@@ -1962,6 +1973,45 @@
360 );
361 };
362
363+sub set_vars {
364+ my ($self, $file) = @_;
365+ $file ||= $self->{file} || __FILE__;
366+
367+ my %user_vars;
368+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
369+ if ( $user_vars ) {
370+ foreach my $var_val ( @$user_vars ) {
371+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
372+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
373+ $user_vars{$var} = {
374+ val => $val,
375+ default => 0,
376+ };
377+ }
378+ }
379+
380+ my %default_vars;
381+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
382+ if ( $default_vars ) {
383+ %default_vars = map {
384+ my $var_val = $_;
385+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
386+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
387+ $var => {
388+ val => $val,
389+ default => 1,
390+ };
391+ } split("\n", $default_vars);
392+ }
393+
394+ my %vars = (
395+ %default_vars, # first the tool's defaults
396+ %user_vars, # then the user's which overwrite the defaults
397+ );
398+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
399+ return \%vars;
400+}
401+
402 sub _d {
403 my ($package, undef, $line) = caller 0;
404 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
405
406=== modified file 'bin/pt-fifo-split'
407--- bin/pt-fifo-split 2013-07-18 17:31:04 +0000
408+++ bin/pt-fifo-split 2013-08-14 00:47:54 +0000
409@@ -36,6 +36,7 @@
410
411 use List::Util qw(max);
412 use Getopt::Long;
413+use Data::Dumper;
414
415 my $POD_link_re = '[LC]<"?([^">]+)"?>';
416
417@@ -431,11 +432,21 @@
418 my $long = exists $self->{opts}->{$opt} ? $opt
419 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
420 : die "Getopt::Long gave a nonexistent option: $opt";
421-
422 $opt = $self->{opts}->{$long};
423 if ( $opt->{is_cumulative} ) {
424 $opt->{value}++;
425 }
426+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
427+ my $next_opt = $1;
428+ if ( exists $self->{opts}->{$next_opt}
429+ || exists $self->{short_opts}->{$next_opt} ) {
430+ $self->save_error("--$long requires a string value");
431+ return;
432+ }
433+ else {
434+ $opt->{value} = $val;
435+ }
436+ }
437 else {
438 $opt->{value} = $val;
439 }
440@@ -1019,6 +1030,45 @@
441 );
442 };
443
444+sub set_vars {
445+ my ($self, $file) = @_;
446+ $file ||= $self->{file} || __FILE__;
447+
448+ my %user_vars;
449+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
450+ if ( $user_vars ) {
451+ foreach my $var_val ( @$user_vars ) {
452+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
453+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
454+ $user_vars{$var} = {
455+ val => $val,
456+ default => 0,
457+ };
458+ }
459+ }
460+
461+ my %default_vars;
462+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
463+ if ( $default_vars ) {
464+ %default_vars = map {
465+ my $var_val = $_;
466+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
467+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
468+ $var => {
469+ val => $val,
470+ default => 1,
471+ };
472+ } split("\n", $default_vars);
473+ }
474+
475+ my %vars = (
476+ %default_vars, # first the tool's defaults
477+ %user_vars, # then the user's which overwrite the defaults
478+ );
479+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
480+ return \%vars;
481+}
482+
483 sub _d {
484 my ($package, undef, $line) = caller 0;
485 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
486
487=== modified file 'bin/pt-find'
488--- bin/pt-find 2013-07-18 17:31:04 +0000
489+++ bin/pt-find 2013-08-14 00:47:54 +0000
490@@ -438,6 +438,7 @@
491
492 use List::Util qw(max);
493 use Getopt::Long;
494+use Data::Dumper;
495
496 my $POD_link_re = '[LC]<"?([^">]+)"?>';
497
498@@ -833,11 +834,21 @@
499 my $long = exists $self->{opts}->{$opt} ? $opt
500 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
501 : die "Getopt::Long gave a nonexistent option: $opt";
502-
503 $opt = $self->{opts}->{$long};
504 if ( $opt->{is_cumulative} ) {
505 $opt->{value}++;
506 }
507+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
508+ my $next_opt = $1;
509+ if ( exists $self->{opts}->{$next_opt}
510+ || exists $self->{short_opts}->{$next_opt} ) {
511+ $self->save_error("--$long requires a string value");
512+ return;
513+ }
514+ else {
515+ $opt->{value} = $val;
516+ }
517+ }
518 else {
519 $opt->{value} = $val;
520 }
521@@ -1421,6 +1432,45 @@
522 );
523 };
524
525+sub set_vars {
526+ my ($self, $file) = @_;
527+ $file ||= $self->{file} || __FILE__;
528+
529+ my %user_vars;
530+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
531+ if ( $user_vars ) {
532+ foreach my $var_val ( @$user_vars ) {
533+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
534+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
535+ $user_vars{$var} = {
536+ val => $val,
537+ default => 0,
538+ };
539+ }
540+ }
541+
542+ my %default_vars;
543+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
544+ if ( $default_vars ) {
545+ %default_vars = map {
546+ my $var_val = $_;
547+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
548+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
549+ $var => {
550+ val => $val,
551+ default => 1,
552+ };
553+ } split("\n", $default_vars);
554+ }
555+
556+ my %vars = (
557+ %default_vars, # first the tool's defaults
558+ %user_vars, # then the user's which overwrite the defaults
559+ );
560+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
561+ return \%vars;
562+}
563+
564 sub _d {
565 my ($package, undef, $line) = caller 0;
566 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
567
568=== modified file 'bin/pt-fingerprint'
569--- bin/pt-fingerprint 2013-07-18 17:31:04 +0000
570+++ bin/pt-fingerprint 2013-08-14 00:47:54 +0000
571@@ -37,6 +37,7 @@
572
573 use List::Util qw(max);
574 use Getopt::Long;
575+use Data::Dumper;
576
577 my $POD_link_re = '[LC]<"?([^">]+)"?>';
578
579@@ -432,11 +433,21 @@
580 my $long = exists $self->{opts}->{$opt} ? $opt
581 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
582 : die "Getopt::Long gave a nonexistent option: $opt";
583-
584 $opt = $self->{opts}->{$long};
585 if ( $opt->{is_cumulative} ) {
586 $opt->{value}++;
587 }
588+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
589+ my $next_opt = $1;
590+ if ( exists $self->{opts}->{$next_opt}
591+ || exists $self->{short_opts}->{$next_opt} ) {
592+ $self->save_error("--$long requires a string value");
593+ return;
594+ }
595+ else {
596+ $opt->{value} = $val;
597+ }
598+ }
599 else {
600 $opt->{value} = $val;
601 }
602@@ -1020,6 +1031,45 @@
603 );
604 };
605
606+sub set_vars {
607+ my ($self, $file) = @_;
608+ $file ||= $self->{file} || __FILE__;
609+
610+ my %user_vars;
611+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
612+ if ( $user_vars ) {
613+ foreach my $var_val ( @$user_vars ) {
614+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
615+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
616+ $user_vars{$var} = {
617+ val => $val,
618+ default => 0,
619+ };
620+ }
621+ }
622+
623+ my %default_vars;
624+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
625+ if ( $default_vars ) {
626+ %default_vars = map {
627+ my $var_val = $_;
628+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
629+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
630+ $var => {
631+ val => $val,
632+ default => 1,
633+ };
634+ } split("\n", $default_vars);
635+ }
636+
637+ my %vars = (
638+ %default_vars, # first the tool's defaults
639+ %user_vars, # then the user's which overwrite the defaults
640+ );
641+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
642+ return \%vars;
643+}
644+
645 sub _d {
646 my ($package, undef, $line) = caller 0;
647 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
648
649=== modified file 'bin/pt-fk-error-logger'
650--- bin/pt-fk-error-logger 2013-07-18 17:31:04 +0000
651+++ bin/pt-fk-error-logger 2013-08-14 00:47:54 +0000
652@@ -61,6 +61,7 @@
653
654 use List::Util qw(max);
655 use Getopt::Long;
656+use Data::Dumper;
657
658 my $POD_link_re = '[LC]<"?([^">]+)"?>';
659
660@@ -456,11 +457,21 @@
661 my $long = exists $self->{opts}->{$opt} ? $opt
662 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
663 : die "Getopt::Long gave a nonexistent option: $opt";
664-
665 $opt = $self->{opts}->{$long};
666 if ( $opt->{is_cumulative} ) {
667 $opt->{value}++;
668 }
669+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
670+ my $next_opt = $1;
671+ if ( exists $self->{opts}->{$next_opt}
672+ || exists $self->{short_opts}->{$next_opt} ) {
673+ $self->save_error("--$long requires a string value");
674+ return;
675+ }
676+ else {
677+ $opt->{value} = $val;
678+ }
679+ }
680 else {
681 $opt->{value} = $val;
682 }
683@@ -1044,6 +1055,45 @@
684 );
685 };
686
687+sub set_vars {
688+ my ($self, $file) = @_;
689+ $file ||= $self->{file} || __FILE__;
690+
691+ my %user_vars;
692+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
693+ if ( $user_vars ) {
694+ foreach my $var_val ( @$user_vars ) {
695+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
696+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
697+ $user_vars{$var} = {
698+ val => $val,
699+ default => 0,
700+ };
701+ }
702+ }
703+
704+ my %default_vars;
705+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
706+ if ( $default_vars ) {
707+ %default_vars = map {
708+ my $var_val = $_;
709+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
710+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
711+ $var => {
712+ val => $val,
713+ default => 1,
714+ };
715+ } split("\n", $default_vars);
716+ }
717+
718+ my %vars = (
719+ %default_vars, # first the tool's defaults
720+ %user_vars, # then the user's which overwrite the defaults
721+ );
722+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
723+ return \%vars;
724+}
725+
726 sub _d {
727 my ($package, undef, $line) = caller 0;
728 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
729
730=== modified file 'bin/pt-heartbeat'
731--- bin/pt-heartbeat 2013-07-18 17:31:04 +0000
732+++ bin/pt-heartbeat 2013-08-14 00:47:54 +0000
733@@ -798,6 +798,7 @@
734
735 use List::Util qw(max);
736 use Getopt::Long;
737+use Data::Dumper;
738
739 my $POD_link_re = '[LC]<"?([^">]+)"?>';
740
741@@ -1193,11 +1194,21 @@
742 my $long = exists $self->{opts}->{$opt} ? $opt
743 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
744 : die "Getopt::Long gave a nonexistent option: $opt";
745-
746 $opt = $self->{opts}->{$long};
747 if ( $opt->{is_cumulative} ) {
748 $opt->{value}++;
749 }
750+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
751+ my $next_opt = $1;
752+ if ( exists $self->{opts}->{$next_opt}
753+ || exists $self->{short_opts}->{$next_opt} ) {
754+ $self->save_error("--$long requires a string value");
755+ return;
756+ }
757+ else {
758+ $opt->{value} = $val;
759+ }
760+ }
761 else {
762 $opt->{value} = $val;
763 }
764@@ -1781,6 +1792,45 @@
765 );
766 };
767
768+sub set_vars {
769+ my ($self, $file) = @_;
770+ $file ||= $self->{file} || __FILE__;
771+
772+ my %user_vars;
773+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
774+ if ( $user_vars ) {
775+ foreach my $var_val ( @$user_vars ) {
776+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
777+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
778+ $user_vars{$var} = {
779+ val => $val,
780+ default => 0,
781+ };
782+ }
783+ }
784+
785+ my %default_vars;
786+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
787+ if ( $default_vars ) {
788+ %default_vars = map {
789+ my $var_val = $_;
790+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
791+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
792+ $var => {
793+ val => $val,
794+ default => 1,
795+ };
796+ } split("\n", $default_vars);
797+ }
798+
799+ my %vars = (
800+ %default_vars, # first the tool's defaults
801+ %user_vars, # then the user's which overwrite the defaults
802+ );
803+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
804+ return \%vars;
805+}
806+
807 sub _d {
808 my ($package, undef, $line) = caller 0;
809 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
810
811=== modified file 'bin/pt-index-usage'
812--- bin/pt-index-usage 2013-07-18 17:31:04 +0000
813+++ bin/pt-index-usage 2013-08-14 00:47:54 +0000
814@@ -574,6 +574,7 @@
815
816 use List::Util qw(max);
817 use Getopt::Long;
818+use Data::Dumper;
819
820 my $POD_link_re = '[LC]<"?([^">]+)"?>';
821
822@@ -969,11 +970,21 @@
823 my $long = exists $self->{opts}->{$opt} ? $opt
824 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
825 : die "Getopt::Long gave a nonexistent option: $opt";
826-
827 $opt = $self->{opts}->{$long};
828 if ( $opt->{is_cumulative} ) {
829 $opt->{value}++;
830 }
831+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
832+ my $next_opt = $1;
833+ if ( exists $self->{opts}->{$next_opt}
834+ || exists $self->{short_opts}->{$next_opt} ) {
835+ $self->save_error("--$long requires a string value");
836+ return;
837+ }
838+ else {
839+ $opt->{value} = $val;
840+ }
841+ }
842 else {
843 $opt->{value} = $val;
844 }
845@@ -1557,6 +1568,45 @@
846 );
847 };
848
849+sub set_vars {
850+ my ($self, $file) = @_;
851+ $file ||= $self->{file} || __FILE__;
852+
853+ my %user_vars;
854+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
855+ if ( $user_vars ) {
856+ foreach my $var_val ( @$user_vars ) {
857+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
858+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
859+ $user_vars{$var} = {
860+ val => $val,
861+ default => 0,
862+ };
863+ }
864+ }
865+
866+ my %default_vars;
867+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
868+ if ( $default_vars ) {
869+ %default_vars = map {
870+ my $var_val = $_;
871+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
872+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
873+ $var => {
874+ val => $val,
875+ default => 1,
876+ };
877+ } split("\n", $default_vars);
878+ }
879+
880+ my %vars = (
881+ %default_vars, # first the tool's defaults
882+ %user_vars, # then the user's which overwrite the defaults
883+ );
884+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
885+ return \%vars;
886+}
887+
888 sub _d {
889 my ($package, undef, $line) = caller 0;
890 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
891
892=== modified file 'bin/pt-kill'
893--- bin/pt-kill 2013-07-18 17:31:04 +0000
894+++ bin/pt-kill 2013-08-14 00:47:54 +0000
895@@ -69,6 +69,7 @@
896
897 use List::Util qw(max);
898 use Getopt::Long;
899+use Data::Dumper;
900
901 my $POD_link_re = '[LC]<"?([^">]+)"?>';
902
903@@ -464,11 +465,21 @@
904 my $long = exists $self->{opts}->{$opt} ? $opt
905 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
906 : die "Getopt::Long gave a nonexistent option: $opt";
907-
908 $opt = $self->{opts}->{$long};
909 if ( $opt->{is_cumulative} ) {
910 $opt->{value}++;
911 }
912+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
913+ my $next_opt = $1;
914+ if ( exists $self->{opts}->{$next_opt}
915+ || exists $self->{short_opts}->{$next_opt} ) {
916+ $self->save_error("--$long requires a string value");
917+ return;
918+ }
919+ else {
920+ $opt->{value} = $val;
921+ }
922+ }
923 else {
924 $opt->{value} = $val;
925 }
926@@ -1052,6 +1063,45 @@
927 );
928 };
929
930+sub set_vars {
931+ my ($self, $file) = @_;
932+ $file ||= $self->{file} || __FILE__;
933+
934+ my %user_vars;
935+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
936+ if ( $user_vars ) {
937+ foreach my $var_val ( @$user_vars ) {
938+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
939+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
940+ $user_vars{$var} = {
941+ val => $val,
942+ default => 0,
943+ };
944+ }
945+ }
946+
947+ my %default_vars;
948+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
949+ if ( $default_vars ) {
950+ %default_vars = map {
951+ my $var_val = $_;
952+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
953+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
954+ $var => {
955+ val => $val,
956+ default => 1,
957+ };
958+ } split("\n", $default_vars);
959+ }
960+
961+ my %vars = (
962+ %default_vars, # first the tool's defaults
963+ %user_vars, # then the user's which overwrite the defaults
964+ );
965+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
966+ return \%vars;
967+}
968+
969 sub _d {
970 my ($package, undef, $line) = caller 0;
971 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
972
973=== modified file 'bin/pt-log-player'
974--- bin/pt-log-player 2013-07-18 17:31:04 +0000
975+++ bin/pt-log-player 2013-08-14 00:47:54 +0000
976@@ -41,6 +41,7 @@
977
978 use List::Util qw(max);
979 use Getopt::Long;
980+use Data::Dumper;
981
982 my $POD_link_re = '[LC]<"?([^">]+)"?>';
983
984@@ -436,11 +437,21 @@
985 my $long = exists $self->{opts}->{$opt} ? $opt
986 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
987 : die "Getopt::Long gave a nonexistent option: $opt";
988-
989 $opt = $self->{opts}->{$long};
990 if ( $opt->{is_cumulative} ) {
991 $opt->{value}++;
992 }
993+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
994+ my $next_opt = $1;
995+ if ( exists $self->{opts}->{$next_opt}
996+ || exists $self->{short_opts}->{$next_opt} ) {
997+ $self->save_error("--$long requires a string value");
998+ return;
999+ }
1000+ else {
1001+ $opt->{value} = $val;
1002+ }
1003+ }
1004 else {
1005 $opt->{value} = $val;
1006 }
1007@@ -1024,6 +1035,45 @@
1008 );
1009 };
1010
1011+sub set_vars {
1012+ my ($self, $file) = @_;
1013+ $file ||= $self->{file} || __FILE__;
1014+
1015+ my %user_vars;
1016+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1017+ if ( $user_vars ) {
1018+ foreach my $var_val ( @$user_vars ) {
1019+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1020+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1021+ $user_vars{$var} = {
1022+ val => $val,
1023+ default => 0,
1024+ };
1025+ }
1026+ }
1027+
1028+ my %default_vars;
1029+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1030+ if ( $default_vars ) {
1031+ %default_vars = map {
1032+ my $var_val = $_;
1033+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1034+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1035+ $var => {
1036+ val => $val,
1037+ default => 1,
1038+ };
1039+ } split("\n", $default_vars);
1040+ }
1041+
1042+ my %vars = (
1043+ %default_vars, # first the tool's defaults
1044+ %user_vars, # then the user's which overwrite the defaults
1045+ );
1046+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1047+ return \%vars;
1048+}
1049+
1050 sub _d {
1051 my ($package, undef, $line) = caller 0;
1052 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1053
1054=== modified file 'bin/pt-online-schema-change'
1055--- bin/pt-online-schema-change 2013-07-18 17:31:04 +0000
1056+++ bin/pt-online-schema-change 2013-08-14 00:47:54 +0000
1057@@ -77,6 +77,7 @@
1058
1059 use List::Util qw(max);
1060 use Getopt::Long;
1061+use Data::Dumper;
1062
1063 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1064
1065@@ -472,11 +473,21 @@
1066 my $long = exists $self->{opts}->{$opt} ? $opt
1067 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1068 : die "Getopt::Long gave a nonexistent option: $opt";
1069-
1070 $opt = $self->{opts}->{$long};
1071 if ( $opt->{is_cumulative} ) {
1072 $opt->{value}++;
1073 }
1074+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1075+ my $next_opt = $1;
1076+ if ( exists $self->{opts}->{$next_opt}
1077+ || exists $self->{short_opts}->{$next_opt} ) {
1078+ $self->save_error("--$long requires a string value");
1079+ return;
1080+ }
1081+ else {
1082+ $opt->{value} = $val;
1083+ }
1084+ }
1085 else {
1086 $opt->{value} = $val;
1087 }
1088@@ -1060,6 +1071,45 @@
1089 );
1090 };
1091
1092+sub set_vars {
1093+ my ($self, $file) = @_;
1094+ $file ||= $self->{file} || __FILE__;
1095+
1096+ my %user_vars;
1097+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1098+ if ( $user_vars ) {
1099+ foreach my $var_val ( @$user_vars ) {
1100+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1101+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1102+ $user_vars{$var} = {
1103+ val => $val,
1104+ default => 0,
1105+ };
1106+ }
1107+ }
1108+
1109+ my %default_vars;
1110+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1111+ if ( $default_vars ) {
1112+ %default_vars = map {
1113+ my $var_val = $_;
1114+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1115+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1116+ $var => {
1117+ val => $val,
1118+ default => 1,
1119+ };
1120+ } split("\n", $default_vars);
1121+ }
1122+
1123+ my %vars = (
1124+ %default_vars, # first the tool's defaults
1125+ %user_vars, # then the user's which overwrite the defaults
1126+ );
1127+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1128+ return \%vars;
1129+}
1130+
1131 sub _d {
1132 my ($package, undef, $line) = caller 0;
1133 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1134
1135=== modified file 'bin/pt-query-advisor'
1136--- bin/pt-query-advisor 2013-07-18 17:31:04 +0000
1137+++ bin/pt-query-advisor 2013-08-14 00:47:54 +0000
1138@@ -449,6 +449,7 @@
1139
1140 use List::Util qw(max);
1141 use Getopt::Long;
1142+use Data::Dumper;
1143
1144 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1145
1146@@ -844,11 +845,21 @@
1147 my $long = exists $self->{opts}->{$opt} ? $opt
1148 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1149 : die "Getopt::Long gave a nonexistent option: $opt";
1150-
1151 $opt = $self->{opts}->{$long};
1152 if ( $opt->{is_cumulative} ) {
1153 $opt->{value}++;
1154 }
1155+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1156+ my $next_opt = $1;
1157+ if ( exists $self->{opts}->{$next_opt}
1158+ || exists $self->{short_opts}->{$next_opt} ) {
1159+ $self->save_error("--$long requires a string value");
1160+ return;
1161+ }
1162+ else {
1163+ $opt->{value} = $val;
1164+ }
1165+ }
1166 else {
1167 $opt->{value} = $val;
1168 }
1169@@ -1432,6 +1443,45 @@
1170 );
1171 };
1172
1173+sub set_vars {
1174+ my ($self, $file) = @_;
1175+ $file ||= $self->{file} || __FILE__;
1176+
1177+ my %user_vars;
1178+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1179+ if ( $user_vars ) {
1180+ foreach my $var_val ( @$user_vars ) {
1181+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1182+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1183+ $user_vars{$var} = {
1184+ val => $val,
1185+ default => 0,
1186+ };
1187+ }
1188+ }
1189+
1190+ my %default_vars;
1191+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1192+ if ( $default_vars ) {
1193+ %default_vars = map {
1194+ my $var_val = $_;
1195+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1196+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1197+ $var => {
1198+ val => $val,
1199+ default => 1,
1200+ };
1201+ } split("\n", $default_vars);
1202+ }
1203+
1204+ my %vars = (
1205+ %default_vars, # first the tool's defaults
1206+ %user_vars, # then the user's which overwrite the defaults
1207+ );
1208+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1209+ return \%vars;
1210+}
1211+
1212 sub _d {
1213 my ($package, undef, $line) = caller 0;
1214 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1215
1216=== modified file 'bin/pt-query-digest'
1217--- bin/pt-query-digest 2013-07-18 17:31:04 +0000
1218+++ bin/pt-query-digest 2013-08-14 00:47:54 +0000
1219@@ -593,6 +593,7 @@
1220
1221 use List::Util qw(max);
1222 use Getopt::Long;
1223+use Data::Dumper;
1224
1225 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1226
1227@@ -988,11 +989,21 @@
1228 my $long = exists $self->{opts}->{$opt} ? $opt
1229 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1230 : die "Getopt::Long gave a nonexistent option: $opt";
1231-
1232 $opt = $self->{opts}->{$long};
1233 if ( $opt->{is_cumulative} ) {
1234 $opt->{value}++;
1235 }
1236+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1237+ my $next_opt = $1;
1238+ if ( exists $self->{opts}->{$next_opt}
1239+ || exists $self->{short_opts}->{$next_opt} ) {
1240+ $self->save_error("--$long requires a string value");
1241+ return;
1242+ }
1243+ else {
1244+ $opt->{value} = $val;
1245+ }
1246+ }
1247 else {
1248 $opt->{value} = $val;
1249 }
1250@@ -1576,6 +1587,45 @@
1251 );
1252 };
1253
1254+sub set_vars {
1255+ my ($self, $file) = @_;
1256+ $file ||= $self->{file} || __FILE__;
1257+
1258+ my %user_vars;
1259+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1260+ if ( $user_vars ) {
1261+ foreach my $var_val ( @$user_vars ) {
1262+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1263+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1264+ $user_vars{$var} = {
1265+ val => $val,
1266+ default => 0,
1267+ };
1268+ }
1269+ }
1270+
1271+ my %default_vars;
1272+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1273+ if ( $default_vars ) {
1274+ %default_vars = map {
1275+ my $var_val = $_;
1276+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1277+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1278+ $var => {
1279+ val => $val,
1280+ default => 1,
1281+ };
1282+ } split("\n", $default_vars);
1283+ }
1284+
1285+ my %vars = (
1286+ %default_vars, # first the tool's defaults
1287+ %user_vars, # then the user's which overwrite the defaults
1288+ );
1289+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1290+ return \%vars;
1291+}
1292+
1293 sub _d {
1294 my ($package, undef, $line) = caller 0;
1295 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1296
1297=== modified file 'bin/pt-show-grants'
1298--- bin/pt-show-grants 2013-07-18 17:31:04 +0000
1299+++ bin/pt-show-grants 2013-08-14 00:47:54 +0000
1300@@ -37,6 +37,7 @@
1301
1302 use List::Util qw(max);
1303 use Getopt::Long;
1304+use Data::Dumper;
1305
1306 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1307
1308@@ -432,11 +433,21 @@
1309 my $long = exists $self->{opts}->{$opt} ? $opt
1310 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1311 : die "Getopt::Long gave a nonexistent option: $opt";
1312-
1313 $opt = $self->{opts}->{$long};
1314 if ( $opt->{is_cumulative} ) {
1315 $opt->{value}++;
1316 }
1317+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1318+ my $next_opt = $1;
1319+ if ( exists $self->{opts}->{$next_opt}
1320+ || exists $self->{short_opts}->{$next_opt} ) {
1321+ $self->save_error("--$long requires a string value");
1322+ return;
1323+ }
1324+ else {
1325+ $opt->{value} = $val;
1326+ }
1327+ }
1328 else {
1329 $opt->{value} = $val;
1330 }
1331@@ -1020,6 +1031,45 @@
1332 );
1333 };
1334
1335+sub set_vars {
1336+ my ($self, $file) = @_;
1337+ $file ||= $self->{file} || __FILE__;
1338+
1339+ my %user_vars;
1340+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1341+ if ( $user_vars ) {
1342+ foreach my $var_val ( @$user_vars ) {
1343+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1344+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1345+ $user_vars{$var} = {
1346+ val => $val,
1347+ default => 0,
1348+ };
1349+ }
1350+ }
1351+
1352+ my %default_vars;
1353+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1354+ if ( $default_vars ) {
1355+ %default_vars = map {
1356+ my $var_val = $_;
1357+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1358+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1359+ $var => {
1360+ val => $val,
1361+ default => 1,
1362+ };
1363+ } split("\n", $default_vars);
1364+ }
1365+
1366+ my %vars = (
1367+ %default_vars, # first the tool's defaults
1368+ %user_vars, # then the user's which overwrite the defaults
1369+ );
1370+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1371+ return \%vars;
1372+}
1373+
1374 sub _d {
1375 my ($package, undef, $line) = caller 0;
1376 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1377
1378=== modified file 'bin/pt-slave-delay'
1379--- bin/pt-slave-delay 2013-07-18 17:31:04 +0000
1380+++ bin/pt-slave-delay 2013-08-14 00:47:54 +0000
1381@@ -62,6 +62,7 @@
1382
1383 use List::Util qw(max);
1384 use Getopt::Long;
1385+use Data::Dumper;
1386
1387 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1388
1389@@ -457,11 +458,21 @@
1390 my $long = exists $self->{opts}->{$opt} ? $opt
1391 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1392 : die "Getopt::Long gave a nonexistent option: $opt";
1393-
1394 $opt = $self->{opts}->{$long};
1395 if ( $opt->{is_cumulative} ) {
1396 $opt->{value}++;
1397 }
1398+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1399+ my $next_opt = $1;
1400+ if ( exists $self->{opts}->{$next_opt}
1401+ || exists $self->{short_opts}->{$next_opt} ) {
1402+ $self->save_error("--$long requires a string value");
1403+ return;
1404+ }
1405+ else {
1406+ $opt->{value} = $val;
1407+ }
1408+ }
1409 else {
1410 $opt->{value} = $val;
1411 }
1412@@ -1045,6 +1056,45 @@
1413 );
1414 };
1415
1416+sub set_vars {
1417+ my ($self, $file) = @_;
1418+ $file ||= $self->{file} || __FILE__;
1419+
1420+ my %user_vars;
1421+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1422+ if ( $user_vars ) {
1423+ foreach my $var_val ( @$user_vars ) {
1424+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1425+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1426+ $user_vars{$var} = {
1427+ val => $val,
1428+ default => 0,
1429+ };
1430+ }
1431+ }
1432+
1433+ my %default_vars;
1434+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1435+ if ( $default_vars ) {
1436+ %default_vars = map {
1437+ my $var_val = $_;
1438+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1439+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1440+ $var => {
1441+ val => $val,
1442+ default => 1,
1443+ };
1444+ } split("\n", $default_vars);
1445+ }
1446+
1447+ my %vars = (
1448+ %default_vars, # first the tool's defaults
1449+ %user_vars, # then the user's which overwrite the defaults
1450+ );
1451+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1452+ return \%vars;
1453+}
1454+
1455 sub _d {
1456 my ($package, undef, $line) = caller 0;
1457 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1458
1459=== modified file 'bin/pt-slave-find'
1460--- bin/pt-slave-find 2013-07-18 17:31:04 +0000
1461+++ bin/pt-slave-find 2013-08-14 00:47:54 +0000
1462@@ -41,6 +41,7 @@
1463
1464 use List::Util qw(max);
1465 use Getopt::Long;
1466+use Data::Dumper;
1467
1468 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1469
1470@@ -436,11 +437,21 @@
1471 my $long = exists $self->{opts}->{$opt} ? $opt
1472 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1473 : die "Getopt::Long gave a nonexistent option: $opt";
1474-
1475 $opt = $self->{opts}->{$long};
1476 if ( $opt->{is_cumulative} ) {
1477 $opt->{value}++;
1478 }
1479+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1480+ my $next_opt = $1;
1481+ if ( exists $self->{opts}->{$next_opt}
1482+ || exists $self->{short_opts}->{$next_opt} ) {
1483+ $self->save_error("--$long requires a string value");
1484+ return;
1485+ }
1486+ else {
1487+ $opt->{value} = $val;
1488+ }
1489+ }
1490 else {
1491 $opt->{value} = $val;
1492 }
1493@@ -1024,6 +1035,45 @@
1494 );
1495 };
1496
1497+sub set_vars {
1498+ my ($self, $file) = @_;
1499+ $file ||= $self->{file} || __FILE__;
1500+
1501+ my %user_vars;
1502+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1503+ if ( $user_vars ) {
1504+ foreach my $var_val ( @$user_vars ) {
1505+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1506+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1507+ $user_vars{$var} = {
1508+ val => $val,
1509+ default => 0,
1510+ };
1511+ }
1512+ }
1513+
1514+ my %default_vars;
1515+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1516+ if ( $default_vars ) {
1517+ %default_vars = map {
1518+ my $var_val = $_;
1519+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1520+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1521+ $var => {
1522+ val => $val,
1523+ default => 1,
1524+ };
1525+ } split("\n", $default_vars);
1526+ }
1527+
1528+ my %vars = (
1529+ %default_vars, # first the tool's defaults
1530+ %user_vars, # then the user's which overwrite the defaults
1531+ );
1532+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1533+ return \%vars;
1534+}
1535+
1536 sub _d {
1537 my ($package, undef, $line) = caller 0;
1538 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1539
1540=== modified file 'bin/pt-slave-restart'
1541--- bin/pt-slave-restart 2013-07-18 17:31:04 +0000
1542+++ bin/pt-slave-restart 2013-08-14 00:47:54 +0000
1543@@ -189,6 +189,7 @@
1544
1545 use List::Util qw(max);
1546 use Getopt::Long;
1547+use Data::Dumper;
1548
1549 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1550
1551@@ -584,11 +585,21 @@
1552 my $long = exists $self->{opts}->{$opt} ? $opt
1553 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1554 : die "Getopt::Long gave a nonexistent option: $opt";
1555-
1556 $opt = $self->{opts}->{$long};
1557 if ( $opt->{is_cumulative} ) {
1558 $opt->{value}++;
1559 }
1560+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1561+ my $next_opt = $1;
1562+ if ( exists $self->{opts}->{$next_opt}
1563+ || exists $self->{short_opts}->{$next_opt} ) {
1564+ $self->save_error("--$long requires a string value");
1565+ return;
1566+ }
1567+ else {
1568+ $opt->{value} = $val;
1569+ }
1570+ }
1571 else {
1572 $opt->{value} = $val;
1573 }
1574@@ -1172,6 +1183,45 @@
1575 );
1576 };
1577
1578+sub set_vars {
1579+ my ($self, $file) = @_;
1580+ $file ||= $self->{file} || __FILE__;
1581+
1582+ my %user_vars;
1583+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1584+ if ( $user_vars ) {
1585+ foreach my $var_val ( @$user_vars ) {
1586+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1587+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1588+ $user_vars{$var} = {
1589+ val => $val,
1590+ default => 0,
1591+ };
1592+ }
1593+ }
1594+
1595+ my %default_vars;
1596+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1597+ if ( $default_vars ) {
1598+ %default_vars = map {
1599+ my $var_val = $_;
1600+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1601+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1602+ $var => {
1603+ val => $val,
1604+ default => 1,
1605+ };
1606+ } split("\n", $default_vars);
1607+ }
1608+
1609+ my %vars = (
1610+ %default_vars, # first the tool's defaults
1611+ %user_vars, # then the user's which overwrite the defaults
1612+ );
1613+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1614+ return \%vars;
1615+}
1616+
1617 sub _d {
1618 my ($package, undef, $line) = caller 0;
1619 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1620
1621=== modified file 'bin/pt-table-checksum'
1622--- bin/pt-table-checksum 2013-07-18 17:31:04 +0000
1623+++ bin/pt-table-checksum 2013-08-14 00:47:54 +0000
1624@@ -1762,6 +1762,7 @@
1625
1626 use List::Util qw(max);
1627 use Getopt::Long;
1628+use Data::Dumper;
1629
1630 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1631
1632@@ -2157,11 +2158,21 @@
1633 my $long = exists $self->{opts}->{$opt} ? $opt
1634 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1635 : die "Getopt::Long gave a nonexistent option: $opt";
1636-
1637 $opt = $self->{opts}->{$long};
1638 if ( $opt->{is_cumulative} ) {
1639 $opt->{value}++;
1640 }
1641+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1642+ my $next_opt = $1;
1643+ if ( exists $self->{opts}->{$next_opt}
1644+ || exists $self->{short_opts}->{$next_opt} ) {
1645+ $self->save_error("--$long requires a string value");
1646+ return;
1647+ }
1648+ else {
1649+ $opt->{value} = $val;
1650+ }
1651+ }
1652 else {
1653 $opt->{value} = $val;
1654 }
1655@@ -2745,6 +2756,45 @@
1656 );
1657 };
1658
1659+sub set_vars {
1660+ my ($self, $file) = @_;
1661+ $file ||= $self->{file} || __FILE__;
1662+
1663+ my %user_vars;
1664+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1665+ if ( $user_vars ) {
1666+ foreach my $var_val ( @$user_vars ) {
1667+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1668+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1669+ $user_vars{$var} = {
1670+ val => $val,
1671+ default => 0,
1672+ };
1673+ }
1674+ }
1675+
1676+ my %default_vars;
1677+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1678+ if ( $default_vars ) {
1679+ %default_vars = map {
1680+ my $var_val = $_;
1681+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1682+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1683+ $var => {
1684+ val => $val,
1685+ default => 1,
1686+ };
1687+ } split("\n", $default_vars);
1688+ }
1689+
1690+ my %vars = (
1691+ %default_vars, # first the tool's defaults
1692+ %user_vars, # then the user's which overwrite the defaults
1693+ );
1694+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1695+ return \%vars;
1696+}
1697+
1698 sub _d {
1699 my ($package, undef, $line) = caller 0;
1700 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1701
1702=== modified file 'bin/pt-table-sync'
1703--- bin/pt-table-sync 2013-07-18 17:31:04 +0000
1704+++ bin/pt-table-sync 2013-08-14 00:47:54 +0000
1705@@ -78,6 +78,7 @@
1706
1707 use List::Util qw(max);
1708 use Getopt::Long;
1709+use Data::Dumper;
1710
1711 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1712
1713@@ -473,11 +474,21 @@
1714 my $long = exists $self->{opts}->{$opt} ? $opt
1715 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1716 : die "Getopt::Long gave a nonexistent option: $opt";
1717-
1718 $opt = $self->{opts}->{$long};
1719 if ( $opt->{is_cumulative} ) {
1720 $opt->{value}++;
1721 }
1722+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1723+ my $next_opt = $1;
1724+ if ( exists $self->{opts}->{$next_opt}
1725+ || exists $self->{short_opts}->{$next_opt} ) {
1726+ $self->save_error("--$long requires a string value");
1727+ return;
1728+ }
1729+ else {
1730+ $opt->{value} = $val;
1731+ }
1732+ }
1733 else {
1734 $opt->{value} = $val;
1735 }
1736@@ -1061,6 +1072,45 @@
1737 );
1738 };
1739
1740+sub set_vars {
1741+ my ($self, $file) = @_;
1742+ $file ||= $self->{file} || __FILE__;
1743+
1744+ my %user_vars;
1745+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1746+ if ( $user_vars ) {
1747+ foreach my $var_val ( @$user_vars ) {
1748+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1749+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1750+ $user_vars{$var} = {
1751+ val => $val,
1752+ default => 0,
1753+ };
1754+ }
1755+ }
1756+
1757+ my %default_vars;
1758+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1759+ if ( $default_vars ) {
1760+ %default_vars = map {
1761+ my $var_val = $_;
1762+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1763+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1764+ $var => {
1765+ val => $val,
1766+ default => 1,
1767+ };
1768+ } split("\n", $default_vars);
1769+ }
1770+
1771+ my %vars = (
1772+ %default_vars, # first the tool's defaults
1773+ %user_vars, # then the user's which overwrite the defaults
1774+ );
1775+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1776+ return \%vars;
1777+}
1778+
1779 sub _d {
1780 my ($package, undef, $line) = caller 0;
1781 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1782
1783=== modified file 'bin/pt-table-usage'
1784--- bin/pt-table-usage 2013-07-18 17:31:04 +0000
1785+++ bin/pt-table-usage 2013-08-14 00:47:54 +0000
1786@@ -428,6 +428,7 @@
1787
1788 use List::Util qw(max);
1789 use Getopt::Long;
1790+use Data::Dumper;
1791
1792 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1793
1794@@ -449,7 +450,6 @@
1795 'default' => 1,
1796 'cumulative' => 1,
1797 'negatable' => 1,
1798- 'value_is_optional' => 1,
1799 );
1800
1801 my $self = {
1802@@ -691,10 +691,9 @@
1803 $opt->{short} = undef;
1804 }
1805
1806- $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0;
1807- $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0;
1808- $opt->{optional_value} = $opt->{spec} =~ m/:/ ? 1 : 0;
1809- $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0;
1810+ $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0;
1811+ $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0;
1812+ $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0;
1813
1814 $opt->{group} ||= 'default';
1815 $self->{groups}->{ $opt->{group} }->{$long} = 1;
1816@@ -825,12 +824,22 @@
1817 my $long = exists $self->{opts}->{$opt} ? $opt
1818 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1819 : die "Getopt::Long gave a nonexistent option: $opt";
1820-
1821 $opt = $self->{opts}->{$long};
1822 if ( $opt->{is_cumulative} ) {
1823 $opt->{value}++;
1824 }
1825- elsif ( !($opt->{optional_value} && !$val) ) {
1826+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1827+ my $next_opt = $1;
1828+ if ( exists $self->{opts}->{$next_opt}
1829+ || exists $self->{short_opts}->{$next_opt} ) {
1830+ $self->save_error("--$long requires a string value");
1831+ return;
1832+ }
1833+ else {
1834+ $opt->{value} = $val;
1835+ }
1836+ }
1837+ else {
1838 $opt->{value} = $val;
1839 }
1840 $opt->{got} = 1;
1841@@ -1210,7 +1219,7 @@
1842 $desc .= ". Optional suffix s=seconds, m=minutes, h=hours, "
1843 . "d=days; if no suffix, $s is used.";
1844 }
1845- $desc = join("\n$rpad", grep { $_ } $desc =~ m/(.{0,$rcol})(?:\s+|$)/g);
1846+ $desc = join("\n$rpad", grep { $_ } $desc =~ m/(.{0,$rcol}(?!\W))(?:\s+|(?<=\W)|$)/g);
1847 $desc =~ s/ +$//mg;
1848 if ( $short ) {
1849 $usage .= sprintf(" --%-${maxs}s -%s %s\n", $long, $short, $desc);
1850@@ -1371,12 +1380,11 @@
1851 sub _parse_attribs {
1852 my ( $self, $option, $attribs ) = @_;
1853 my $types = $self->{types};
1854- my $eq = $attribs->{'value_is_optional'} ? ':' : '=';
1855 return $option
1856 . ($attribs->{'short form'} ? '|' . $attribs->{'short form'} : '' )
1857 . ($attribs->{'negatable'} ? '!' : '' )
1858 . ($attribs->{'cumulative'} ? '+' : '' )
1859- . ($attribs->{'type'} ? $eq . $types->{$attribs->{type}} : '' );
1860+ . ($attribs->{'type'} ? '=' . $types->{$attribs->{type}} : '' );
1861 }
1862
1863 sub _parse_synopsis {
1864@@ -1414,6 +1422,45 @@
1865 );
1866 };
1867
1868+sub set_vars {
1869+ my ($self, $file) = @_;
1870+ $file ||= $self->{file} || __FILE__;
1871+
1872+ my %user_vars;
1873+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1874+ if ( $user_vars ) {
1875+ foreach my $var_val ( @$user_vars ) {
1876+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1877+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1878+ $user_vars{$var} = {
1879+ val => $val,
1880+ default => 0,
1881+ };
1882+ }
1883+ }
1884+
1885+ my %default_vars;
1886+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1887+ if ( $default_vars ) {
1888+ %default_vars = map {
1889+ my $var_val = $_;
1890+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1891+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1892+ $var => {
1893+ val => $val,
1894+ default => 1,
1895+ };
1896+ } split("\n", $default_vars);
1897+ }
1898+
1899+ my %vars = (
1900+ %default_vars, # first the tool's defaults
1901+ %user_vars, # then the user's which overwrite the defaults
1902+ );
1903+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1904+ return \%vars;
1905+}
1906+
1907 sub _d {
1908 my ($package, undef, $line) = caller 0;
1909 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1910
1911=== modified file 'bin/pt-tcp-model'
1912--- bin/pt-tcp-model 2013-07-18 17:31:04 +0000
1913+++ bin/pt-tcp-model 2013-08-14 00:47:54 +0000
1914@@ -40,6 +40,7 @@
1915
1916 use List::Util qw(max);
1917 use Getopt::Long;
1918+use Data::Dumper;
1919
1920 my $POD_link_re = '[LC]<"?([^">]+)"?>';
1921
1922@@ -435,11 +436,21 @@
1923 my $long = exists $self->{opts}->{$opt} ? $opt
1924 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
1925 : die "Getopt::Long gave a nonexistent option: $opt";
1926-
1927 $opt = $self->{opts}->{$long};
1928 if ( $opt->{is_cumulative} ) {
1929 $opt->{value}++;
1930 }
1931+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
1932+ my $next_opt = $1;
1933+ if ( exists $self->{opts}->{$next_opt}
1934+ || exists $self->{short_opts}->{$next_opt} ) {
1935+ $self->save_error("--$long requires a string value");
1936+ return;
1937+ }
1938+ else {
1939+ $opt->{value} = $val;
1940+ }
1941+ }
1942 else {
1943 $opt->{value} = $val;
1944 }
1945@@ -1023,6 +1034,45 @@
1946 );
1947 };
1948
1949+sub set_vars {
1950+ my ($self, $file) = @_;
1951+ $file ||= $self->{file} || __FILE__;
1952+
1953+ my %user_vars;
1954+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
1955+ if ( $user_vars ) {
1956+ foreach my $var_val ( @$user_vars ) {
1957+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1958+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1959+ $user_vars{$var} = {
1960+ val => $val,
1961+ default => 0,
1962+ };
1963+ }
1964+ }
1965+
1966+ my %default_vars;
1967+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
1968+ if ( $default_vars ) {
1969+ %default_vars = map {
1970+ my $var_val = $_;
1971+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
1972+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
1973+ $var => {
1974+ val => $val,
1975+ default => 1,
1976+ };
1977+ } split("\n", $default_vars);
1978+ }
1979+
1980+ my %vars = (
1981+ %default_vars, # first the tool's defaults
1982+ %user_vars, # then the user's which overwrite the defaults
1983+ );
1984+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
1985+ return \%vars;
1986+}
1987+
1988 sub _d {
1989 my ($package, undef, $line) = caller 0;
1990 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
1991
1992=== modified file 'bin/pt-trend'
1993--- bin/pt-trend 2013-07-18 17:31:04 +0000
1994+++ bin/pt-trend 2013-08-14 00:47:54 +0000
1995@@ -40,6 +40,7 @@
1996
1997 use List::Util qw(max);
1998 use Getopt::Long;
1999+use Data::Dumper;
2000
2001 my $POD_link_re = '[LC]<"?([^">]+)"?>';
2002
2003@@ -435,11 +436,21 @@
2004 my $long = exists $self->{opts}->{$opt} ? $opt
2005 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
2006 : die "Getopt::Long gave a nonexistent option: $opt";
2007-
2008 $opt = $self->{opts}->{$long};
2009 if ( $opt->{is_cumulative} ) {
2010 $opt->{value}++;
2011 }
2012+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
2013+ my $next_opt = $1;
2014+ if ( exists $self->{opts}->{$next_opt}
2015+ || exists $self->{short_opts}->{$next_opt} ) {
2016+ $self->save_error("--$long requires a string value");
2017+ return;
2018+ }
2019+ else {
2020+ $opt->{value} = $val;
2021+ }
2022+ }
2023 else {
2024 $opt->{value} = $val;
2025 }
2026@@ -1023,6 +1034,45 @@
2027 );
2028 };
2029
2030+sub set_vars {
2031+ my ($self, $file) = @_;
2032+ $file ||= $self->{file} || __FILE__;
2033+
2034+ my %user_vars;
2035+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
2036+ if ( $user_vars ) {
2037+ foreach my $var_val ( @$user_vars ) {
2038+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2039+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2040+ $user_vars{$var} = {
2041+ val => $val,
2042+ default => 0,
2043+ };
2044+ }
2045+ }
2046+
2047+ my %default_vars;
2048+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
2049+ if ( $default_vars ) {
2050+ %default_vars = map {
2051+ my $var_val = $_;
2052+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2053+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2054+ $var => {
2055+ val => $val,
2056+ default => 1,
2057+ };
2058+ } split("\n", $default_vars);
2059+ }
2060+
2061+ my %vars = (
2062+ %default_vars, # first the tool's defaults
2063+ %user_vars, # then the user's which overwrite the defaults
2064+ );
2065+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
2066+ return \%vars;
2067+}
2068+
2069 sub _d {
2070 my ($package, undef, $line) = caller 0;
2071 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
2072
2073=== modified file 'bin/pt-upgrade'
2074--- bin/pt-upgrade 2013-07-18 17:31:04 +0000
2075+++ bin/pt-upgrade 2013-08-14 00:47:54 +0000
2076@@ -998,6 +998,7 @@
2077
2078 use List::Util qw(max);
2079 use Getopt::Long;
2080+use Data::Dumper;
2081
2082 my $POD_link_re = '[LC]<"?([^">]+)"?>';
2083
2084@@ -1393,11 +1394,21 @@
2085 my $long = exists $self->{opts}->{$opt} ? $opt
2086 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
2087 : die "Getopt::Long gave a nonexistent option: $opt";
2088-
2089 $opt = $self->{opts}->{$long};
2090 if ( $opt->{is_cumulative} ) {
2091 $opt->{value}++;
2092 }
2093+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
2094+ my $next_opt = $1;
2095+ if ( exists $self->{opts}->{$next_opt}
2096+ || exists $self->{short_opts}->{$next_opt} ) {
2097+ $self->save_error("--$long requires a string value");
2098+ return;
2099+ }
2100+ else {
2101+ $opt->{value} = $val;
2102+ }
2103+ }
2104 else {
2105 $opt->{value} = $val;
2106 }
2107@@ -1981,6 +1992,45 @@
2108 );
2109 };
2110
2111+sub set_vars {
2112+ my ($self, $file) = @_;
2113+ $file ||= $self->{file} || __FILE__;
2114+
2115+ my %user_vars;
2116+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
2117+ if ( $user_vars ) {
2118+ foreach my $var_val ( @$user_vars ) {
2119+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2120+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2121+ $user_vars{$var} = {
2122+ val => $val,
2123+ default => 0,
2124+ };
2125+ }
2126+ }
2127+
2128+ my %default_vars;
2129+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
2130+ if ( $default_vars ) {
2131+ %default_vars = map {
2132+ my $var_val = $_;
2133+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2134+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2135+ $var => {
2136+ val => $val,
2137+ default => 1,
2138+ };
2139+ } split("\n", $default_vars);
2140+ }
2141+
2142+ my %vars = (
2143+ %default_vars, # first the tool's defaults
2144+ %user_vars, # then the user's which overwrite the defaults
2145+ );
2146+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
2147+ return \%vars;
2148+}
2149+
2150 sub _d {
2151 my ($package, undef, $line) = caller 0;
2152 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
2153
2154=== modified file 'bin/pt-variable-advisor'
2155--- bin/pt-variable-advisor 2013-07-18 17:31:04 +0000
2156+++ bin/pt-variable-advisor 2013-08-14 00:47:54 +0000
2157@@ -66,6 +66,7 @@
2158
2159 use List::Util qw(max);
2160 use Getopt::Long;
2161+use Data::Dumper;
2162
2163 my $POD_link_re = '[LC]<"?([^">]+)"?>';
2164
2165@@ -461,11 +462,21 @@
2166 my $long = exists $self->{opts}->{$opt} ? $opt
2167 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
2168 : die "Getopt::Long gave a nonexistent option: $opt";
2169-
2170 $opt = $self->{opts}->{$long};
2171 if ( $opt->{is_cumulative} ) {
2172 $opt->{value}++;
2173 }
2174+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
2175+ my $next_opt = $1;
2176+ if ( exists $self->{opts}->{$next_opt}
2177+ || exists $self->{short_opts}->{$next_opt} ) {
2178+ $self->save_error("--$long requires a string value");
2179+ return;
2180+ }
2181+ else {
2182+ $opt->{value} = $val;
2183+ }
2184+ }
2185 else {
2186 $opt->{value} = $val;
2187 }
2188@@ -1049,6 +1060,45 @@
2189 );
2190 };
2191
2192+sub set_vars {
2193+ my ($self, $file) = @_;
2194+ $file ||= $self->{file} || __FILE__;
2195+
2196+ my %user_vars;
2197+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
2198+ if ( $user_vars ) {
2199+ foreach my $var_val ( @$user_vars ) {
2200+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2201+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2202+ $user_vars{$var} = {
2203+ val => $val,
2204+ default => 0,
2205+ };
2206+ }
2207+ }
2208+
2209+ my %default_vars;
2210+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
2211+ if ( $default_vars ) {
2212+ %default_vars = map {
2213+ my $var_val = $_;
2214+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2215+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2216+ $var => {
2217+ val => $val,
2218+ default => 1,
2219+ };
2220+ } split("\n", $default_vars);
2221+ }
2222+
2223+ my %vars = (
2224+ %default_vars, # first the tool's defaults
2225+ %user_vars, # then the user's which overwrite the defaults
2226+ );
2227+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
2228+ return \%vars;
2229+}
2230+
2231 sub _d {
2232 my ($package, undef, $line) = caller 0;
2233 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
2234
2235=== modified file 'bin/pt-visual-explain'
2236--- bin/pt-visual-explain 2013-07-18 17:31:04 +0000
2237+++ bin/pt-visual-explain 2013-08-14 00:47:54 +0000
2238@@ -711,6 +711,7 @@
2239
2240 use List::Util qw(max);
2241 use Getopt::Long;
2242+use Data::Dumper;
2243
2244 my $POD_link_re = '[LC]<"?([^">]+)"?>';
2245
2246@@ -732,7 +733,6 @@
2247 'default' => 1,
2248 'cumulative' => 1,
2249 'negatable' => 1,
2250- 'value_is_optional' => 1,
2251 );
2252
2253 my $self = {
2254@@ -974,10 +974,9 @@
2255 $opt->{short} = undef;
2256 }
2257
2258- $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0;
2259- $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0;
2260- $opt->{optional_value} = $opt->{spec} =~ m/:/ ? 1 : 0;
2261- $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0;
2262+ $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0;
2263+ $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0;
2264+ $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0;
2265
2266 $opt->{group} ||= 'default';
2267 $self->{groups}->{ $opt->{group} }->{$long} = 1;
2268@@ -1108,12 +1107,22 @@
2269 my $long = exists $self->{opts}->{$opt} ? $opt
2270 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
2271 : die "Getopt::Long gave a nonexistent option: $opt";
2272-
2273 $opt = $self->{opts}->{$long};
2274 if ( $opt->{is_cumulative} ) {
2275 $opt->{value}++;
2276 }
2277- elsif ( !($opt->{optional_value} && !$val) ) {
2278+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
2279+ my $next_opt = $1;
2280+ if ( exists $self->{opts}->{$next_opt}
2281+ || exists $self->{short_opts}->{$next_opt} ) {
2282+ $self->save_error("--$long requires a string value");
2283+ return;
2284+ }
2285+ else {
2286+ $opt->{value} = $val;
2287+ }
2288+ }
2289+ else {
2290 $opt->{value} = $val;
2291 }
2292 $opt->{got} = 1;
2293@@ -1493,7 +1502,7 @@
2294 $desc .= ". Optional suffix s=seconds, m=minutes, h=hours, "
2295 . "d=days; if no suffix, $s is used.";
2296 }
2297- $desc = join("\n$rpad", grep { $_ } $desc =~ m/(.{0,$rcol})(?:\s+|$)/g);
2298+ $desc = join("\n$rpad", grep { $_ } $desc =~ m/(.{0,$rcol}(?!\W))(?:\s+|(?<=\W)|$)/g);
2299 $desc =~ s/ +$//mg;
2300 if ( $short ) {
2301 $usage .= sprintf(" --%-${maxs}s -%s %s\n", $long, $short, $desc);
2302@@ -1654,12 +1663,11 @@
2303 sub _parse_attribs {
2304 my ( $self, $option, $attribs ) = @_;
2305 my $types = $self->{types};
2306- my $eq = $attribs->{'value_is_optional'} ? ':' : '=';
2307 return $option
2308 . ($attribs->{'short form'} ? '|' . $attribs->{'short form'} : '' )
2309 . ($attribs->{'negatable'} ? '!' : '' )
2310 . ($attribs->{'cumulative'} ? '+' : '' )
2311- . ($attribs->{'type'} ? $eq . $types->{$attribs->{type}} : '' );
2312+ . ($attribs->{'type'} ? '=' . $types->{$attribs->{type}} : '' );
2313 }
2314
2315 sub _parse_synopsis {
2316@@ -1697,6 +1705,45 @@
2317 );
2318 };
2319
2320+sub set_vars {
2321+ my ($self, $file) = @_;
2322+ $file ||= $self->{file} || __FILE__;
2323+
2324+ my %user_vars;
2325+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
2326+ if ( $user_vars ) {
2327+ foreach my $var_val ( @$user_vars ) {
2328+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2329+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2330+ $user_vars{$var} = {
2331+ val => $val,
2332+ default => 0,
2333+ };
2334+ }
2335+ }
2336+
2337+ my %default_vars;
2338+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
2339+ if ( $default_vars ) {
2340+ %default_vars = map {
2341+ my $var_val = $_;
2342+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2343+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2344+ $var => {
2345+ val => $val,
2346+ default => 1,
2347+ };
2348+ } split("\n", $default_vars);
2349+ }
2350+
2351+ my %vars = (
2352+ %default_vars, # first the tool's defaults
2353+ %user_vars, # then the user's which overwrite the defaults
2354+ );
2355+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
2356+ return \%vars;
2357+}
2358+
2359 sub _d {
2360 my ($package, undef, $line) = caller 0;
2361 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
2362
2363=== modified file 'lib/OptionParser.pm'
2364--- lib/OptionParser.pm 2013-01-03 00:19:16 +0000
2365+++ lib/OptionParser.pm 2013-08-14 00:47:54 +0000
2366@@ -18,45 +18,6 @@
2367 # OptionParser package
2368 # ###########################################################################
2369 {
2370-# Package: OptionParser
2371-# OptionParser parses command line options from a tool's POD. By default
2372-# it parses a description and usage from the POD's SYNOPSIS section and
2373-# command line options from the OPTIONS section.
2374-#
2375-# The SYNOPSIS section should look like,
2376-# (start code)
2377-# =head1 SYNOPSIS
2378-#
2379-# Usage: mk-archiver [OPTION...] --source DSN --where WHERE
2380-#
2381-# mk-archiver nibbles records from a MySQL table. The --source and --dest
2382-# arguments use DSN syntax; if COPY is yes, --dest defaults to the key's value
2383-# from --source.
2384-#
2385-# Examples:
2386-# ...
2387-# (end code)
2388-# The key, required parts are the "Usage:" line and the following description
2389-# paragraph.
2390-#
2391-# The OPTIONS section shoud look like,
2392-# (start code)
2393-# =head1 OPTIONS
2394-#
2395-# Optional rules, one per line.
2396-#
2397-# =over
2398-#
2399-# =item --analyze
2400-#
2401-# type: string
2402-#
2403-# Run ANALYZE TABLE afterwards on L<"--source"> and/or L<"--dest">.
2404-# ect.
2405-# (end code)
2406-# The option's full name is given as the "=item". The next, optional para
2407-# is the option's attributes. And the next, required para is the option's
2408-# description (the first period-terminated sentence).
2409 package OptionParser;
2410
2411 use strict;
2412@@ -66,6 +27,7 @@
2413
2414 use List::Util qw(max);
2415 use Getopt::Long;
2416+use Data::Dumper;
2417
2418 my $POD_link_re = '[LC]<"?([^">]+)"?>';
2419
2420@@ -592,12 +554,23 @@
2421 my $long = exists $self->{opts}->{$opt} ? $opt
2422 : exists $self->{short_opts}->{$opt} ? $self->{short_opts}->{$opt}
2423 : die "Getopt::Long gave a nonexistent option: $opt";
2424-
2425 # Reassign $opt.
2426 $opt = $self->{opts}->{$long};
2427 if ( $opt->{is_cumulative} ) {
2428 $opt->{value}++;
2429 }
2430+ elsif ( ($opt->{type} || '') eq 's' && $val =~ m/^--?(.+)/ ) {
2431+ # https://bugs.launchpad.net/percona-toolkit/+bug/1199589
2432+ my $next_opt = $1;
2433+ if ( exists $self->{opts}->{$next_opt}
2434+ || exists $self->{short_opts}->{$next_opt} ) {
2435+ $self->save_error("--$long requires a string value");
2436+ return;
2437+ }
2438+ else {
2439+ $opt->{value} = $val;
2440+ }
2441+ }
2442 else {
2443 $opt->{value} = $val;
2444 }
2445@@ -1318,6 +1291,45 @@
2446 );
2447 };
2448
2449+sub set_vars {
2450+ my ($self, $file) = @_;
2451+ $file ||= $self->{file} || __FILE__;
2452+
2453+ my %user_vars;
2454+ my $user_vars = $self->has('set-vars') ? $self->get('set-vars') : undef;
2455+ if ( $user_vars ) {
2456+ foreach my $var_val ( @$user_vars ) {
2457+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2458+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2459+ $user_vars{$var} = {
2460+ val => $val,
2461+ default => 0,
2462+ };
2463+ }
2464+ }
2465+
2466+ my %default_vars;
2467+ my $default_vars = $self->read_para_after($file, qr/MAGIC_set_vars/);
2468+ if ( $default_vars ) {
2469+ %default_vars = map {
2470+ my $var_val = $_;
2471+ my ($var, $val) = $var_val =~ m/([^\s=]+)=(\S+)/;
2472+ die "Invalid --set-vars value: $var_val\n" unless $var && defined $val;
2473+ $var => {
2474+ val => $val,
2475+ default => 1,
2476+ };
2477+ } split("\n", $default_vars);
2478+ }
2479+
2480+ my %vars = (
2481+ %default_vars, # first the tool's defaults
2482+ %user_vars, # then the user's which overwrite the defaults
2483+ );
2484+ PTDEBUG && _d('--set-vars:', Dumper(\%vars));
2485+ return \%vars;
2486+}
2487+
2488 sub _d {
2489 my ($package, undef, $line) = caller 0;
2490 @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
2491
2492=== modified file 't/lib/OptionParser.t'
2493--- t/lib/OptionParser.t 2012-11-09 16:31:13 +0000
2494+++ t/lib/OptionParser.t 2013-08-14 00:47:54 +0000
2495@@ -2022,6 +2022,59 @@
2496 );
2497
2498 # #############################################################################
2499+# https://bugs.launchpad.net/percona-toolkit/+bug/1199589
2500+# pt-archiver deletes data despite --dry-run
2501+# #############################################################################
2502+
2503+# From the issue: "One problem is that --optimize is not being used correctly:
2504+# the option takes an argument: d, s, or ds (see --analyze). The real problem
2505+# is that --optimize is consuming the next option, which is --dry-run in this
2506+# case. This shouldn't happen; it means the option parser is failing to notice
2507+# that --dry-run is not the string val to --optimize but rather an option;
2508+# it should catch this and the tool should fail to start with an error like
2509+# "--optimize requires a value".
2510+
2511+@ARGV = qw(--optimize --dry-run --ascend-first --where 1=1 --purge --source localhost);
2512+$o = new OptionParser(file => "$trunk/bin/pt-archiver");
2513+$o->get_specs();
2514+$o->get_opts();
2515+
2516+$output = output(
2517+ sub { $o->usage_or_errors(undef, 1); },
2518+);
2519+
2520+like(
2521+ $output,
2522+ qr/--optimize requires a string value/,
2523+ "String opts don't consume the next opt (bug 1199589)"
2524+);
2525+
2526+is(
2527+ $o->get('optimize'),
2528+ undef,
2529+ "--optimize didn't consume --dry-run (bug 1199589)"
2530+);
2531+
2532+@ARGV = qw(--optimize ds --dry-run --ascend-first --where 1=1 --purge --source localhost);
2533+$o->get_opts();
2534+
2535+$output = output(
2536+ sub { $o->usage_or_errors(undef, 1); },
2537+);
2538+
2539+is(
2540+ $output,
2541+ '',
2542+ "String opts still work (bug 1199589)"
2543+);
2544+
2545+is(
2546+ $o->get('optimize'),
2547+ 'ds',
2548+ "--optimize got its value (bug 1199589)"
2549+);
2550+
2551+# #############################################################################
2552 # Done.
2553 # #############################################################################
2554 {
2555
2556=== added file 't/pt-archiver/bugs.t'
2557--- t/pt-archiver/bugs.t 1970-01-01 00:00:00 +0000
2558+++ t/pt-archiver/bugs.t 2013-08-14 00:47:54 +0000
2559@@ -0,0 +1,56 @@
2560+#!/usr/bin/env perl
2561+
2562+BEGIN {
2563+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
2564+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
2565+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
2566+};
2567+
2568+use strict;
2569+use warnings FATAL => 'all';
2570+use English qw(-no_match_vars);
2571+use Test::More;
2572+use Data::Dumper;
2573+
2574+use PerconaTest;
2575+use Sandbox;
2576+require "$trunk/bin/pt-archiver";
2577+
2578+my $dp = new DSNParser(opts=>$dsn_opts);
2579+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
2580+my $master_dbh = $sb->get_dbh_for('master');
2581+
2582+if ( !$master_dbh ) {
2583+ plan skip_all => 'Cannot connect to sandbox master';
2584+}
2585+
2586+my $output;
2587+my $cnf = "/tmp/12345/my.sandbox.cnf";
2588+my $cmd = "$trunk/bin/pt-archiver";
2589+
2590+$sb->create_dbs($master_dbh, ['test']);
2591+$sb->load_file('master', 't/pt-archiver/samples/tables1-4.sql');
2592+
2593+# ###########################################################################
2594+# pt-archiver deletes data despite --dry-run
2595+# https://bugs.launchpad.net/percona-toolkit/+bug/1199589
2596+# ###########################################################################
2597+
2598+my $rows_before = $master_dbh->selectall_arrayref("SELECT * FROM test.table_1 ORDER BY a");
2599+
2600+$output = `$cmd --optimize --dry-run --purge --where 1=1 --source D=test,t=table_1,F=$cnf 2>&1`;
2601+
2602+my $rows_after = $master_dbh->selectall_arrayref("SELECT * FROM test.table_1 ORDER BY a");
2603+
2604+is_deeply(
2605+ $rows_after,
2606+ $rows_before,
2607+ "--optimize does not consume --dry-run (bug 1199589)"
2608+) or diag(Dumper($rows_after));
2609+
2610+# #############################################################################
2611+# Done.
2612+# #############################################################################
2613+$sb->wipe_clean($master_dbh);
2614+ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
2615+done_testing;

Subscribers

People subscribed via source and target branches