Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package Bio::EnsEMBL::Utils::ConversionSupport;
=head1 NAME
Bio::EnsEMBL::Utils::ConversionSupport - Utility module for Vega release and
schema conversion scripts
=head1 SYNOPSIS
my $serverroot = '/path/to/ensembl';
my $suport = new Bio::EnsEMBL::Utils::ConversionSupport($serverroot);
# parse common options
$support->parse_common_options;
# parse extra options for your script
$support->parse_extra_options('string_opt=s', 'numeric_opt=n');
# ask user if he wants to run script with these parameters
$support->confirm_params;
# see individual method documentation for more stuff
=head1 DESCRIPTION
This module is a collection of common methods and provides helper functions
for the Vega release and schema conversion scripts. Amongst others, it reads
options from a config file, parses commandline options and does logging.
=head1 LICENCE
This code is distributed under an Apache style licence:
Please see http://www.ensembl.org/code_licence.html for details
=head1 AUTHOR
Patrick Meidl <pm2@sanger.ac.uk>
=head1 CONTACT
Post questions to the EnsEMBL development list ensembl-dev@ebi.ac.uk
=cut
use strict;
use warnings;
no warnings 'uninitialized';
use Getopt::Long;
use Text::Wrap;
use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use FindBin qw($Bin $Script);
use POSIX qw(strftime);
=head2 new
Arg[1] : String $serverroot - root directory of your ensembl sandbox
Example : my $support = new Bio::EnsEMBL::Utils::ConversionSupport(
'/path/to/ensembl');
Description : constructor
Return type : Bio::EnsEMBL::Utils::ConversionSupport object
Exceptions : thrown if no serverroot is provided
Caller : general
=cut
sub new {
my $class = shift;
(my $serverroot = shift) or throw("You must supply a serverroot.");
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
my $self = {
'_serverroot' => $serverroot,
'_param' => { interactive => 1 },
'_warnings' => 0,
};
bless ($self, $class);
return $self;
}
=head2 parse_common_options
Example : $support->parse_common_options;
Description : This method reads options from a configuration file and parses
some commandline options that are common to all scripts (like
db connection settings, help, dry-run). Commandline options
will override config file settings.
All options will be accessible via $self->param('name').
Return type : true on success
Exceptions : thrown if configuration file can't be opened
Caller : general
=cut
sub parse_common_options {
my $self = shift;
# read commandline options
my %h;
Getopt::Long::Configure("pass_through");
&GetOptions( \%h,
'dbname|db_name=s',
'host|dbhost|db_host=s',
'port|dbport|db_port=n',
'user|dbuser|db_user=s',
'pass|dbpass|db_pass=s',
'conffile|conf=s',
'logfile|log=s',
Patrick Meidl
committed
'logpath=s',
'interactive|i=s',
'dry_run|dry|n=s',
'help|h|?',
);
# reads config file
my $conffile = $h{'conffile'} || $self->serverroot . "/sanger-plugins/vega/conf/ini-files/Conversion.ini";
if (-e $conffile) {
open(CONF, $conffile) or throw(
"Unable to open configuration file $conffile for reading: $!");
my $serverroot = $self->serverroot;
while (<CONF>) {
Patrick Meidl
committed
chomp;
# remove comments
Patrick Meidl
committed
s/^[#;].*//;
s/\s+[;].*$//;
# read options into internal parameter datastructure, removing whitespace
next unless (/(\w\S*)\s*=\s*(\S*)\s*/);
my $name = $1;
my $val = $2;
if ($val =~ /\$SERVERROOT/) {
$val =~ s/\$SERVERROOT/$serverroot/g;
$val = abs_path($val);
}
$self->param($name, $val);
Patrick Meidl
committed
}
warning("Unable to open configuration file $conffile for reading: $!");
}
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# override configured parameter with commandline options
map { $self->param($_, $h{$_}) } keys %h;
return(1);
}
=head2 parse_extra_options
Arg[1-N] : option descriptors that will be passed on to Getopt::Long
Example : $support->parse_extra_options('string_opt=s', 'numeric_opt=n');
Description : Parse extra commandline options by passing them on to
Getopt::Long and storing parameters in $self->param('name).
Return type : true on success
Exceptions : none (caugth by $self->error)
Caller : general
=cut
sub parse_extra_options {
my ($self, @params) = @_;
Getopt::Long::Configure("no_pass_through");
eval {
# catch warnings to pass to $self->error
local $SIG{__WARN__} = sub { die @_; };
&GetOptions(\%{ $self->{'_param'} }, @params);
};
$self->error($@) if $@;
return(1);
}
=head2 allowed_params
Arg[1-N] : (optional) List of allowed parameters to set
Example : my @allowed = $self->allowed_params(qw(param1 param2));
Description : Getter/setter for allowed parameters. This is used by
$self->confirm_params() to avoid cluttering of output with
conffile entries not relevant for a given script. You can use
$self->get_common_params() as a shortcut to set them.
Return type : Array - list of allowed parameters
Exceptions : none
Caller : general
=cut
sub allowed_params {
my $self = shift;
# setter
if (@_) {
@{ $self->{'_allowed_params'} } = @_;
}
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# getter
if (ref($self->{'_allowed_params'}) eq 'ARRAY') {
return @{ $self->{'_allowed_params'} };
} else {
return ();
}
}
=head2 get_common_params
Example : my @allowed_params = $self->get_common_params, 'extra_param';
Description : Returns a list of commonly used parameters in the conversion
scripts. Shortcut for setting allowed parameters with
$self->allowed_params().
Return type : Array - list of common parameters
Exceptions : none
Caller : general
=cut
sub get_common_params {
return qw(
conffile
dbname
host
port
user
pass
logpath
logfile
logappend
verbose
interactive
dry_run
);
}
=head2 get_lutre_params
Example : my @allowed_params = $self->get_lutre_params, 'extra_param';
Description : Returns a list of commonly used parameters in for working with a loutre db
Return type : Array - list of common parameters
Exceptions : none
Caller : general
=cut
sub get_loutre_params {
return qw(
loutrehost
loutreport
loutreuser
loutrepass
loutredbname
);
}
=head2 confirm_params
Example : $support->confirm_params;
Description : Prints a table of parameters that were collected from config
file and commandline and asks user to confirm if he wants
to proceed.
Return type : true on success
Exceptions : none
Caller : general
=cut
sub confirm_params {
my $self = shift;
# print parameter table
print "Running script with these parameters:\n\n";
print $self->list_all_params;
if ($self->param('host') eq 'web-4-11') {
# ask user if he wants to proceed
exit unless $self->user_proceed("**************\n\n You're working on web-4-11! Is that correct and you want to continue ?\n\n**************");
}
else {
# ask user if he wants to proceed
exit unless $self->user_proceed("Continue?");
}
return(1);
}
=head2 list_all_params
Example : print LOG $support->list_all_params;
Description : prints a table of the parameters used in the script
Return type : String - the table to print
Exceptions : none
Caller : general
=cut
sub list_all_params {
my $self = shift;
my $txt = sprintf " %-20s%-40s\n", qw(PARAMETER VALUE);
$txt .= " " . "-"x70 . "\n";
$Text::Wrap::colums = 72;
my @params = $self->allowed_params;
foreach my $key (@params) {
my @vals = $self->param($key);
if (@vals) {
$txt .= Text::Wrap::wrap( sprintf(' %-20s', $key),
' 'x24,
join(", ", @vals)
) . "\n";
}
}
$txt .= "\n";
return $txt;
}
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
=head2 create_commandline_options
Arg[1] : Hashref $settings - hashref describing what to do
Allowed keys:
allowed_params => 0|1 # use all allowed parameters
exclude => [] # listref of parameters to exclude
replace => {param => newval} # replace value of param with
# newval
Example : $support->create_commandline_options({
allowed_params => 1,
exclude => ['verbose'],
replace => { 'dbname' => 'homo_sapiens_vega_33_35e' }
});
Description : Creates a commandline options string that can be passed to any
other script using ConversionSupport.
Return type : String - commandline options string
Exceptions : none
Caller : general
=cut
sub create_commandline_options {
my ($self, $settings) = @_;
my %param_hash;
# get all allowed parameters
if ($settings->{'allowed_params'}) {
# exclude params explicitly stated
my %exclude = map { $_ => 1 } @{ $settings->{'exclude'} || [] };
foreach my $param ($self->allowed_params) {
unless ($exclude{$param}) {
my ($first, @rest) = $self->param($param);
next unless (defined($first));
if (@rest) {
$first = join(",", $first, @rest);
}
$param_hash{$param} = $first;
}
}
}
# replace values
foreach my $key (keys %{ $settings->{'replace'} || {} }) {
$param_hash{$key} = $settings->{'replace'}->{$key};
}
# create the commandline options string
my $options_string;
foreach my $param (keys %param_hash) {
$options_string .= sprintf("--%s %s ", $param, $param_hash{$param});
}
return $options_string;
}
=head2 check_required_params
Arg[1-N] : List @params - parameters to check
Example : $self->check_required_params(qw(dbname host port));
Description : Checks $self->param to make sure the requested parameters
have been set. Dies if parameters are missing.
Return type : true on success
Exceptions : none
Caller : general
=cut
sub check_required_params {
my ($self, @params) = @_;
my @missing = ();
foreach my $param (@params) {
push @missing, $param unless $self->param($param);
}
if (@missing) {
throw("Missing parameters: @missing.\nYou must specify them on the commandline or in your conffile.\n");
}
return(1);
}
=head2 user_proceed
Arg[1] : (optional) String $text - notification text to present to user
Example : # run a code snipped conditionally
if ($support->user_proceed("Run the next code snipped?")) {
# exit if requested by user
exit unless ($support->user_proceed("Want to continue?"));
Description : If running interactively, the user is asked if he wants to
perform a script action. If he doesn't, this section is skipped
and the script proceeds with the code. When running
non-interactively, the section is run by default.
Return type : TRUE to proceed, FALSE to skip.
Exceptions : none
Caller : general
=cut
sub user_proceed {
my ($self, $text) = @_;
if ($self->param('interactive')) {
print "$text\n" if $text;
print "[y/N] ";
my $input = lc(<>);
chomp $input;
unless ($input eq 'y') {
}
}
return(1);
}
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
=head2 user_confirm
Description : DEPRECATED - please use user_proceed() instead
=cut
sub user_confirm {
my $self = shift;
exit unless $self->user_proceed("Continue?");
}
=head2 read_user_input
Arg[1] : (optional) String $text - notification text to present to user
Example : my $ret = $support->read_user_input("Choose a number [1/2/3]");
if ($ret == 1) {
# do something
} elsif ($ret == 2) {
# do something else
}
Description : If running interactively, the user is asked for input.
Return type : String - user's input
Exceptions : none
Caller : general
=cut
sub read_user_input {
my ($self, $text) = @_;
if ($self->param('interactive')) {
print "$text\n" if $text;
my $input = <>;
chomp $input;
return $input;
}
}
=head2 comma_to_list
Arg[1-N] : list of parameter names to parse
Example : $support->comma_to_list('chromosomes');
Description : Transparently converts comma-separated lists into arrays (to
allow different styles of commandline options, see perldoc
Getopt::Long for details). Parameters are converted in place
(accessible through $self->param('name')).
Return type : true on success
Exceptions : none
Caller : general
=cut
sub comma_to_list {
my $self = shift;
foreach my $param (@_) {
$self->param($param,
split (/,/, join (',', $self->param($param))));
}
return(1);
}
Arg[1] : Name of parameter to parse
Example : $support->list_or_file('gene_stable_id');
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
Description : Determines whether a parameter holds a list or it is a filename
to read the list entries from.
Return type : true on success
Exceptions : thrown if list file can't be opened
Caller : general
=cut
sub list_or_file {
my ($self, $param) = @_;
my @vals = $self->param($param);
return unless (@vals);
my $firstval = $vals[0];
if (scalar(@vals) == 1 && -e $firstval) {
# we didn't get a list of values, but a file to read values from
@vals = ();
open(IN, $firstval) or throw("Cannot open $firstval for reading: $!");
while(<IN>){
chomp;
push(@vals, $_);
}
close(IN);
$self->param($param, @vals);
}
$self->comma_to_list($param);
return(1);
}
=head2 param
Arg[1] : Parameter name
Arg[2-N] : (optional) List of values to set
Example : my $dbname = $support->param('dbname');
$support->param('port', 3306);
$support->param('chromosomes', 1, 6, 'X');
Description : Getter/setter for parameters. Accepts single-value params and
list params.
Return type : Scalar value for single-value parameters, array of values for
list parameters
Exceptions : thrown if no parameter name is supplied
Caller : general
=cut
sub param {
my $self = shift;
my $name = shift or throw("You must supply a parameter name");
# setter
if (@_) {
if (scalar(@_) == 1) {
# single value
$self->{'_param'}->{$name} = shift;
} else {
# list of values
Loading full blame...