ensembl-hive  2.7.0
ScriptUtils.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 =cut
19 
20 
21 =head1 CONTACT
22 
23  Please email comments or questions to the public Ensembl
24  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 
26  Questions may also be sent to the Ensembl help desk at
27  <http://www.ensembl.org/Help/Contact>.
28 
29 =cut
30 
31 =head1 NAME
32 
34 
35 =head1 SYNOPSIS
36 
37 =head1 DESCRIPTION
38 
39 =head1 METHODS
40 
41 =cut
42 
43 package Bio::EnsEMBL::Utils::ScriptUtils;
44 
45 use strict;
46 use warnings;
47 no warnings 'uninitialized';
48 
49 use Exporter;
50 our @ISA = qw(Exporter);
51 
52 our @EXPORT_OK = qw(
53  user_proceed
54  commify
55  sort_chromosomes
56  parse_bytes
57  directory_hash
58  path_append
59  dynamic_use
60  inject
61 );
62 
63 
64 =head2 user_proceed
65 
66  Arg[1] : (optional) String $text - notification text to present to user
67  Example : # run a code snipped conditionally
68  if ($support->user_proceed("Run the next code snipped?")) {
69  # run some code
70  }
71 
72  # exit if requested by user
73  exit unless ($support->user_proceed("Want to continue?"));
74  Description : If running interactively, the user is asked if he wants to
75  perform a script action. If he doesn't, this section is skipped
76  and the script proceeds with the code. When running
77  non-interactively, the section is run by default.
78  Return type : TRUE to proceed, FALSE to skip.
79  Exceptions : none
80  Caller : general
81 
82 =cut
83 
84 sub user_proceed {
85  my ($text, $interactive, $default) = @_;
86 
87  unless (defined($default)) {
88  die("Need a default answer for non-interactive runs.");
89  }
90 
91  my $input;
92 
93  if ($interactive) {
94  print "$text\n" if $text;
95  print "[y/N] ";
96 
97  $input = lc(<>);
98  chomp $input;
99  } else {
100  $input = $default;
101  }
102 
103  if ($input eq 'y') {
104  return(1);
105  } else {
106  print "Skipping.\n" if ($interactive);
107  return(0);
108  }
109 }
110 
111 
112 =head2 sort_chromosomes
113 
114  Arg[1] : (optional) Hashref $chr_hashref - Hashref with chr_name as keys
115  Example : my $chr = { '6-COX' => 1, '1' => 1, 'X' => 1 };
116  my @sorted = $support->sort_chromosomes($chr);
117  Description : Sorts chromosomes in an intuitive way (numerically, then
118  alphabetically). If no chromosome hashref is passed, it's
119  retrieve by calling $self->get_chrlength()
120  Return type : List - sorted chromosome names
121  Exceptions : thrown if no hashref is provided
122  Caller : general
123 
124 =cut
125 
126 sub sort_chromosomes {
127  my @chromosomes = @_;
128 
129  return (sort _by_chr_num @chromosomes);
130 }
131 
132 
133 =head2 _by_chr_num
134 
135  Example : my @sorted = sort _by_chr_num qw(X, 6-COX, 14, 7);
136  Description : Subroutine to use in sort for sorting chromosomes. Sorts
137  numerically, then alphabetically
138  Return type : values to be used by sort
139  Exceptions : none
140  Caller : internal ($self->sort_chromosomes)
141 
142 =cut
143 
144 sub _by_chr_num {
145  my @awords = split /-/, $a;
146  my @bwords = split /-/, $b;
147 
148  my $anum = $awords[0];
149  my $bnum = $bwords[0];
150 
151  if ($anum !~ /^[0-9]*$/) {
152  if ($bnum !~ /^[0-9]*$/) {
153  return $anum cmp $bnum;
154  } else {
155  return 1;
156  }
157  }
158  if ($bnum !~ /^[0-9]*$/) {
159  return -1;
160  }
161 
162  if ($anum <=> $bnum) {
163  return $anum <=> $bnum;
164  } else {
165  if ($#awords == 0) {
166  return -1;
167  } elsif ($#bwords == 0) {
168  return 1;
169  } else {
170  return $awords[1] cmp $bwords[1];
171  }
172  }
173 }
174 
175 
176 =head2 commify
177 
178  Arg[1] : Int $num - a number to commify
179  Example : print "An easy to read number: ".$self->commify(100000000);
180  # will print 100,000,000
181  Description : put commas into a number to make it easier to read
182  Return type : a string representing the commified number
183  Exceptions : none
184  Caller : general
185  Status : stable
186 
187 =cut
188 
189 sub commify {
190  my $num = shift;
191 
192  $num = reverse($num);
193  $num =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
194 
195  return scalar reverse $num;
196 }
197 
198 
199 sub parse_bytes {
200  my $bytes = shift;
201 
202  my @suffixes = qw(bytes kb Mb Gb Tb);
203 
204  my $length = length($bytes);
205  my $order = int(($length-1)/3);
206 
207  my $parsed = sprintf('%.1f', $bytes/10**(3*$order));
208 
209  return "$parsed ".$suffixes[$order];
210 }
211 
212 
213 sub directory_hash {
214  my $filename = shift;
215 
216  my (@md5) = md5_hex($filename) =~ /\G(..)/g;
217  return join('/', @md5[0..2]);
218 }
219 
220 
221 sub path_append {
222  my $path1 = shift;
223  my $path2 = shift;
224 
225  # default to current directory
226  $path1 = '.' unless (defined($path1));
227 
228  my $return_path = "$path1/$path2";
229 
230  unless (-d $return_path) {
231  system("mkdir -p $return_path") == 0 or
232  die("Unable to create directory $return_path: $!\n");
233  }
234 
235  return $return_path;
236 }
237 
238 
239 =head2 inject
240 
241  Arg [1] : String $classname - The name of the class to require/import
242  Example : $self->inject('Bio::EnsEMBL::DBSQL::DBAdaptor');
243  Description: Requires and imports the methods for the classname provided,
244  checks the symbol table so that it doesnot re-require modules
245  that have already been required.
246  Returntype : true on success
247  Exceptions : Warns to standard error if module fails to compile
248  Caller : internal
249 
250 =cut
251 
252 sub inject {
253  my $classname = shift;
254  my ($parent_namespace, $module) = $classname =~/^(.*::)(.*)$/ ?
255  ($1,$2) : ('::', $classname);
256  no strict 'refs'; ## no critic
257 
258  # return if module has already been imported
259  return 1 if $parent_namespace->{$module.'::'};
260 
261  eval "require $classname"; ## no critic
262  die("Failed to require $classname: $@") if ($@);
263 
264  $classname->import();
265 
266  return 1;
267 }
268 
269 
270 sub dynamic_use {
271  return inject(@_);
272 }
273 
274 1;
275 
Bio::EnsEMBL::Utils::ScriptUtils
Definition: ScriptUtils.pm:11
run
public run()