Mercurial > repos > cpt > cpt_psm_prep
diff lib/CPT/GalaxyGetOpt.pm @ 1:d724f34e671d draft default tip
planemo upload commit 94b0cd1fff0826c6db3e7dc0c91c0c5a8be8bb0c
author | cpt |
---|---|
date | Mon, 05 Jun 2023 02:50:07 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/CPT/GalaxyGetOpt.pm Mon Jun 05 02:50:07 2023 +0000 @@ -0,0 +1,384 @@ +package CPT::GalaxyGetOpt; +use CPT::ParameterGroup; +use autodie; +use File::Spec::Functions qw[ catfile catdir ]; +use Carp; +no warnings; +use Moose; + +has 'appdesc' => ( is => 'rw', isa => 'Str', default => sub { 'No application description provided' } ); +has 'appid' => ( is => 'rw', isa => 'Str', default => sub { "unknown_app_$0" } ); +has 'appname' => ( is => 'rw', isa => 'Str', default => sub { "Unnamed application $0"} ); +has 'appvers' => ( is => 'rw', isa => 'Str', default => sub { '0.0.1' } ); +has 'registered_outputs' => ( is => 'rw', isa => 'HashRef' ); +has 'opt' => ( is => 'rw', isa => 'Any'); +has filetype_detector => ( + is => 'rw', + isa => 'Any', +); + + +sub getOptions { + my ( $self, %passed_opts ) = @_; + require Getopt::Long::Descriptive; + # these get pushed through, thankfully. This way we can manually check for --genenrate_galaxy_export and exit slightly earlier. + my %args = map { $_ => 1 } @ARGV; + # Sections passed to us + my @script_args = @{ $passed_opts{'options'} }; + my %defaults = @{ $passed_opts{'defaults'} }; + + + + # Output Files Stuff + my @getopt_formatted_outputs; + my %outputs; + # This is originally an array of output files. We transform to a hash for + # easier lookup + foreach(@{$passed_opts{'outputs'}}){ + # Grab name/desc/opts + my ($name, $desc, $opts) = @{$_}; + $outputs{$name} = { + description => $desc, + options => $opts, + required => 1, + }; + my %tmp_opts_fix = %{$opts}; + $tmp_opts_fix{required} = 1; + $tmp_opts_fix{validate} = 'File/Output'; + push(@getopt_formatted_outputs, [$name, $desc, \%tmp_opts_fix]); + + # Adds the {name}_files_path special parameter + my %fp_opts = %{$opts}; + $fp_opts{hidden} = 1; + $fp_opts{value} = "${name}.files_path"; + $fp_opts{default} = "${name}.files_path"; + $fp_opts{required} = 1; + $fp_opts{_galaxy_specific} = 1; + $fp_opts{validate} = "String"; + #$fp_opts{_show_in_galaxy} = 0; + my $desc2 = "Associated HTML files for $name"; + my $name2 = "${name}_files_path"; + my @files_path = ($name2, $desc2, \%fp_opts); + push(@getopt_formatted_outputs, \@files_path); + + # Adds the {name}_format special parameter + my %fp_opts3 = %{$opts}; + #$fp_opts3{hidden} = 1; + $fp_opts3{default} = $fp_opts3{"default_format"}; + $fp_opts3{validate} = "File/OutputFormat"; + $fp_opts{required} = 1; + #$fp_opts3{_galaxy_specific} = 1; + #$fp_opts3{_show_in_galaxy} = 0; + my $desc3 = "Associated Format for $name"; + my $name3 = "${name}_format"; + my @files_path3 = ($name3, $desc3, \%fp_opts3); + push(@getopt_formatted_outputs, \@files_path3); + + # Adds the {name}_files_path special parameter + my %fp_opts4 = %{$opts}; + $fp_opts4{hidden} = 1; + $fp_opts4{value} = "${name}.id"; + $fp_opts4{default} = "${name}.id"; + $fp_opts4{validate} = "String"; + $fp_opts4{_galaxy_specific} = 1; + #$fp_opts4{_show_in_galaxy} = 0; + my $desc4 = "Associated ID Number for $name"; + my $name4 = "${name}_id"; + my @files_path4 = ($name4, $desc4, \%fp_opts4); + push(@getopt_formatted_outputs, \@files_path4); + + } + $self->registered_outputs(\%outputs); + + + # Store the application's name and description + if($defaults{appdesc}){ + $self->appdesc($defaults{appdesc}); + } + if($defaults{appid}){ + $self->appid($defaults{appid}); + } + if($defaults{appname}){ + $self->appname($defaults{appname}); + } + if($defaults{appvers}){ + $self->appvers($defaults{appvers}); + } + + my $usage_desc; + if ( $self->appname() && $self->appdesc() ) { + $usage_desc = sprintf( "%s: %s\n%s [options] <some-arg>", $self->appname(), $self->appdesc(), $0 ); + } + + # Individual parameter parsers + require CPT::Parameter; + # Which are stored in a collection of them + require CPT::ParameterCollection; + + + my $parameterCollection = CPT::ParameterCollection->new(); + + $parameterCollection->push_params( + [ + #['Standard Options'], + #@extra_params, + #[], + ['outfile_supporting' , 'File or folder to output to, necessary when (class == Report || multiple calls to classyReturnResults || multiple standalone output files)' , { hidden => 1, validate => 'String', default => '__new_file_path__', _galaxy_specific => 1, _show_in_galaxy => 0 }], + ['galaxy' , 'Run with galaxy-specific overrides' , {validate => 'Flag' , hidden=>1, _galaxy_specific => 1, _show_in_galaxy => 0}], + ['generate_galaxy_xml' , 'Generate a compatible galaxy-xml file. May need editing' , {validate => 'Flag' , hidden=>1, _galaxy_specific => 1, _show_in_galaxy => 0}], + [], + ['Script Options'], + ] + ); + + # If there's a default specified, we should apply that. + foreach (@script_args) { + # If it's an array, push as is, because either it's old style/label/empty + # However, this doesn't allow setting defaults for things that aren't parameters + # and it won't set defaults for old style + if ( ref $_ eq 'ARRAY' ) { + $parameterCollection->push_param($_); + }elsif( ref $_ eq 'HASH'){ + my $pG = CPT::ParameterGroup->new(); + $pG->set_data($_); + $parameterCollection->push_group($pG); + } + } + + # Our magic output files stuff + $parameterCollection->push_params( + [ + [], + ['Output Files'], + @getopt_formatted_outputs, + ] + ); + + # Other standard options like verbosity/version/etc + $parameterCollection->push_params( + [ + [], + ['Other Standard Options'], + ['verbose|v', 'Be more verbose', {validate => 'Flag', _show_in_galaxy => 0}], + ['version', 'Print version information', {validate => 'Flag', _show_in_galaxy => 0}], + ['help', 'Print usage message and exit', {validate => 'Flag', _show_in_galaxy => 0}], + ], + ); + + # If we want the galaxy_xml, do that before the reduction step is called. + if ( $args{'--version'} ) { + print $self->appvers() . "\n"; + exit 1; + } + + # If we want the galaxy_xml, do that before the reduction step is called. + if ( $args{'--generate_galaxy_xml'} ) { + require CPT::Galaxy; + my $galaxy_xml_generator = CPT::Galaxy->new(); + $galaxy_xml_generator->gen( + full_options => $parameterCollection, + appdesc => $self->appdesc(), + appid => $self->appid(), + appname => $self->appname(), + appvers => $self->appvers(), + defaults => $passed_opts{'defaults'}, + outputs => $passed_opts{'outputs'}, + tests => $passed_opts{'tests'}, + ); + exit 1; + } + + if( $args{'--gen_test'} ){ + require CPT::GenerateTests; + my $tgen = CPT::GenerateTests->new(); + if(defined $passed_opts{'tests'}){ + print $tgen->gen(@{$passed_opts{'tests'}}); + }else{ + print $tgen->gen_empty(); + } + exit 0; + } + + # Now that the options_spec is complete, we reduce to something getopt will be happy with + my @getopt_spec = $parameterCollection->getopt(); + #print STDERR Dumper \@getopt_spec; + #exit 1; + + # It would be nice if there was a way to ensure that it didn't die here... + # Execute getopt + my ( $local_opt, $usage ) = Getopt::Long::Descriptive::describe_options( $usage_desc, @getopt_spec ); + $self->opt($local_opt); + + # Now that we've gotten the user's options, we need to copy their values back to our ParameterCollection + $parameterCollection->populate_from_getopt($self->opt()); + + # If they want help, print + exit + if ( $self->opt && $self->opt->help ) { + print $usage; + exit 1; + } + # Validate their choices + if ( $parameterCollection->validate($self->opt) ) { + return $self->opt; + # Easy access for the script, don't want them to have to deal with PC (just yet) + } + else { + # Some params failed to validate, so we die. + croak "Validation errors were found so cannot continue"; + } +} + +no Moose; +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +CPT::GalaxyGetOpt + +=head1 VERSION + +version 1.99.4 + +=head2 getOptions + + my $ggo = CPT::GalaxyGetOpt->new(); + my $options = $ggo->getOptions( + 'options' => [ + [ 'file', 'Input file', { validate => 'File/Input' } ], + [ + "option" => "Select an option!", + { + validate => 'Option', + options => \%options, + multiple => 1, + } + ], + [ + "float" => "I'm a float", + { validate => 'Float' } + ], + [ + "int" => "I'm an int", + { validate => 'Int', default => [42, 34], required => 1, multiple => 1 } + ], + [], + ['New section'], + [ + "string" => "I'm a simple string", + { validate => 'String' } + ], + [ + 'flag' => 'This is a flag', + { validate => 'Flag' } + ], + ], + 'outputs' => [ + [ + 'my_output_data', + 'Output TXT File', + { + validate => 'File/Output', + required => 1, + default => 'out', + data_format => 'text/plain', + default_format => 'TXT', + } + ], + ], + 'defaults' => [ + 'appid' => 'TemplateScript', + 'appname' => 'Template', + 'appdesc' => 'A basic template for a new CPT application', + 'appvers' => '1.94', + ], + 'tests' => [ + { + test_name => "Default", + params => { + }, + outputs => { + 'my_output_data' => ["out.txt", 'test-data/outputs/template.default.txt' ], + }, + }, + { + test_name => "Option A specified", + params => { + 'int', '10000', + }, + outputs => { + 'my_output_data' => ["out.txt", 'test-data/outputs/template.A.txt' ], + }, + }, + ], + ); + + my @data; + foreach(qw(file int string option float flag)){ + # Create a 2D array of all of our optoins + push(@data, [ $_, $options->{$_}]); + } + + my %table = ( + 'Sheet1' => { + header => [qw(Key Value)], + data => \@data, + } + ); + + # And store it to file! + use CPT::OutputFiles; + my $crr_output = CPT::OutputFiles->new( + name => 'my_output_data', + GGO => $ggo, + ); + $crr_output->CRR(data => \%table); + +Gets command line options, and prints docs. Very convenient, removes the burden of writing any Getopt code from you. + +=head3 Default Options Provided + +=over 4 + +=item * + +help, man - cause an early exit and printing of the POD for your script. + +=item * + +verbose - flag to make the script verbose. Will print everything that is sent to returnResults. Individual scripts should take advantage of this option + +=back + +=head3 Advanced Options Provided + +=over 4 + +=item C<--generate_galaxy_xml> + +Generates valid XML for the tool for use in Galaxy + +=item C<--gen_test> + +Generates code to test the script using specified test data + +=back + +=head1 AUTHOR + +Eric Rasche <rasche.eric@yandex.ru> + +=head1 COPYRIGHT AND LICENSE + +This software is Copyright (c) 2014 by Eric Rasche. + +This is free software, licensed under: + + The GNU General Public License, Version 3, June 2007 + +=cut