From: cmzmasek Date: Fri, 9 Jun 2017 20:11:15 +0000 (-0700) Subject: in progress... X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=92d49095080fd17e379b0ebfaf327b132f804e9c;p=jalview.git in progress... --- diff --git a/forester/ruby/evoruby/lib/evo/msa/msa.rb b/forester/ruby/evoruby/lib/evo/msa/msa.rb index 2d2f93b..1cdc78d 100644 --- a/forester/ruby/evoruby/lib/evo/msa/msa.rb +++ b/forester/ruby/evoruby/lib/evo/msa/msa.rb @@ -17,6 +17,15 @@ module Evoruby @identical_seqs_detected = Array.new @name_to_seq_indices = Hash.new @namestart_to_seq_indices = Hash.new + @name = nil + end + + def get_name + @name + end + + def set_name( name ) + @name = name end def add_sequence( sequence ) @@ -397,7 +406,7 @@ module Evoruby removed end - def trim!( first, last ) + def trim!( first, last, name_suffix = nil ) cols = Array.new() for i in 0 ... get_length() if ( i < first || i > last ) @@ -405,6 +414,58 @@ module Evoruby end end remove_columns!( cols ) + if name_suffix != nil + n = get_number_of_seqs + for s in 0 ... n + seq = get_sequence( s ) + seq.set_name( seq.get_name() + name_suffix ); + end + end + end + + def extract( first, last ) + if !is_aligned() + error_msg = "attempt to extract from unaligned msa" + raise StandardError, error_msg, caller + end + if first < 0 + error_msg = "first < 0" + raise StandardError, error_msg, caller + end + if last >= get_length() + error_msg = "last > length" + raise StandardError, error_msg, caller + end + if first >= last + error_msg = "first >= last" + raise StandardError, error_msg, caller + end + msa = Msa.new() + for i in 0 ... get_number_of_seqs + msa.add_sequence( get_sequence( i ).get_subsequence( first, last ) ) + end + msa + end + + def sliding_extraction( step, size ) + counter = 0 + done = false + msas = Array.new() + while !done + first = counter * step + last = first + size - 1 + if last > get_length() - 1 + last = get_length() - 1 + done = true + end + unless first >= last + counter +=1 + res = extract( first, last) + res.set_name(first.to_s + "-" + last.to_s) + msas << res + end + end + msas end def get_gap_only_columns() diff --git a/forester/ruby/evoruby/lib/evo/tool/msa_processor.rb b/forester/ruby/evoruby/lib/evo/tool/msa_processor.rb index e71a36f..48bb6c1 100644 --- a/forester/ruby/evoruby/lib/evo/tool/msa_processor.rb +++ b/forester/ruby/evoruby/lib/evo/tool/msa_processor.rb @@ -25,9 +25,9 @@ module Evoruby class MsaProcessor PRG_NAME = "msa_pro" - PRG_DATE = "170215" + PRG_DATE = "170609" PRG_DESC = "processing of multiple sequence alignments" - PRG_VERSION = "1.08" + PRG_VERSION = "1.09" WWW = "https://sites.google.com/site/cmzmasek/home/software/forester" NAME_LENGTH_DEFAULT = 10 @@ -50,6 +50,7 @@ module Evoruby REMOVE_MATCHING_SEQUENCES_OPTION = "mr" TRIM_OPTION = "t" + SLIDING_EXTRACTION_OPTION = "se" REMOVE_SEQS_GAP_RATIO_OPTION = "rsgr" REMOVE_SEQS_NON_GAP_LENGTH_OPTION = "rsl" SPLIT = "split" @@ -88,6 +89,9 @@ module Evoruby @split_by_os = false @first = -1 @last = -1 + @window = false + @step = -1 + @size = -1 end def run() @@ -144,6 +148,7 @@ module Evoruby allowed_opts.push( KEEP_MATCHING_SEQUENCES_OPTION ) allowed_opts.push( REMOVE_MATCHING_SEQUENCES_OPTION ) allowed_opts.push( DIE_IF_NAME_TOO_LONG ) + allowed_opts.push( SLIDING_EXTRACTION_OPTION ) disallowed = cla.validate_allowed_options_as_str( allowed_opts ) if ( disallowed.length > 0 ) @@ -275,6 +280,15 @@ module Evoruby puts( "Split : " + @split.to_s ) log << "Split : " + @split.to_s + ld end + if @window + puts( "Sliding window extraction: true" ) + log << "Sliding window extraction: true" + ld + puts( "Sliding window step : " + @step.to_s ) + log << "Sliding window step : " + @step.to_s + ld + puts( "Sliding window size : " + @size.to_s ) + log << "Sliding window size : " + @size.to_s + ld + end + puts() f = MsaFactory.new() @@ -359,8 +373,48 @@ module Evoruby end if ( @trim ) - msa.trim!( @first, @last ) + msa.trim!( @first, @last, '_S' ) + end + + if @window + msas = msa.sliding_extraction( @step, @size ) + begin + io = MsaIO.new() + w = MsaWriter + if ( @pi_output ) + w = PhylipSequentialWriter.new() + w.clean( @clean ) + w.set_max_name_length( @name_length ) + elsif( @fasta_output ) + w = FastaWriter.new() + w.set_line_width( @width ) + w.clean( @clean ) + if ( @name_length_set ) + w.set_max_name_length( @name_length ) + end + elsif( @nexus_output ) + w = NexusWriter.new() + w.clean( @clean ) + w.set_max_name_length( @name_length ) + end + i = 0 + for m in msas + i = i + 1 + name = output + "_" + m.get_name + if @fasta_output + name += ".fasta" + elsif @nexus_output + name += ".nex" + end + io.write_to_file( m, name, w ) + end + Util.print_message( PRG_NAME, "wrote " + msas.length.to_s + " files" ) + log << "wrote " + msas.length.to_s + " files" + ld + rescue Exception => e + Util.fatal_error( PRG_NAME, "error: " + e.to_s, STDOUT ) + end end + if( @rgr >= 0 ) msa.remove_gap_columns_w_gap_ratio!( @rgr ) elsif ( @rgc ) @@ -505,7 +559,7 @@ module Evoruby Util.fatal_error( PRG_NAME, "error: " + e.to_s, STDOUT ) end - if (@split <= 0) && (!@split_by_os) + if (@split <= 0) && (!@split_by_os) && (!@window) unless ( @rg ) if ( msa.is_aligned() ) @@ -757,6 +811,25 @@ module Evoruby @trim = false @first = -1 @last = -1 + @window = false + end + + def set_window() + @split = -1 + @split_by_os = false + @rgc = false + @rgoc = false + @rg = false # fasta only + @rgr = -1 + @rsgr = -1 + @rsl = -1 + @seqs_name_file = nil + @remove_seqs = false + @keep_seqs = false + @trim = false + @first = -1 + @last = -1 + @window = true end def analyze_command_line( cla ) @@ -863,6 +936,29 @@ module Evoruby Util.fatal_error( PRG_NAME, "error: " + e.to_s, STDOUT ) end end + if ( cla.is_option_set?( SLIDING_EXTRACTION_OPTION ) ) + begin + s = cla.get_option_value( SLIDING_EXTRACTION_OPTION ) + if ( s =~ /(\d+)\/(\d+)/ ) + set_window + @window = true + @step = $1.to_i() + @size = $2.to_i() + else + puts( "illegal argument" ) + print_help + exit( -1 ) + end + if (@step <= 0) || (@size <= 0) + puts( "illegal argument" ) + print_help + exit( -1 ) + end + rescue ArgumentError => e + Util.fatal_error( PRG_NAME, "error: " + e.to_s, STDOUT ) + end + end + if ( cla.is_option_set?( REMOVE_SEQS_GAP_RATIO_OPTION ) ) begin f = cla.get_option_value_as_float( REMOVE_SEQS_GAP_RATIO_OPTION ) @@ -921,8 +1017,8 @@ module Evoruby puts() puts( " " + PRG_NAME + ".rb [options] " ) puts() - puts( " options: -" + INPUT_TYPE_OPTION + "=: f for fasta, p for phylip selex type" ) - puts( " -" + OUTPUT_TYPE_OPTION + "=: f for fasta, n for nexus, p for phylip sequential (default)" ) + puts( " options: -" + INPUT_TYPE_OPTION + "=: f for fasta (default), p for phylip/selex type" ) + puts( " -" + OUTPUT_TYPE_OPTION + "=: f for fasta (default), n for nexus, p for phylip sequential" ) puts( " -" + MAXIMAL_NAME_LENGTH_OPTION + "=: n=maximal name length (default for phylip 10, for fasta: unlimited )" ) puts( " -" + DIE_IF_NAME_TOO_LONG + ": die if sequence name too long" ) puts( " -" + WIDTH_OPTION + "=: n=width (fasta output only, default is 60)" ) @@ -940,6 +1036,7 @@ module Evoruby puts( " -" + KEEP_MATCHING_SEQUENCES_OPTION + "= keep only sequences with names containing s" ) puts( " -" + SPLIT + "= split a fasta file into n files of equal number of sequences (expect for " ) puts( " last one), cannot be used with other options" ) + puts( " -" + SLIDING_EXTRACTION_OPTION + "=/: sliding window extraction, cannot be used with other options" ) puts( " -" + REM_RED_OPTION + ": remove redundant sequences" ) puts() end diff --git a/forester/ruby/evoruby/lib/evo/tool/phylogenies_decorator.rb b/forester/ruby/evoruby/lib/evo/tool/phylogenies_decorator.rb index a811899..b2f6446 100644 --- a/forester/ruby/evoruby/lib/evo/tool/phylogenies_decorator.rb +++ b/forester/ruby/evoruby/lib/evo/tool/phylogenies_decorator.rb @@ -21,7 +21,6 @@ module Evoruby DECORATOR_OPTIONS_SEQ_NAMES = '-p -t -mp -or' DECORATOR_OPTIONS_DOMAINS = '-p -t' - DOMAINS_MAPFILE_SUFFIX = '.dff' SLEEP_TIME = 0.01 REMOVE_NI = true TMP_FILE_1 = '___PD1___' @@ -31,9 +30,9 @@ module Evoruby JAVA_HOME = ENV[Constants::JAVA_HOME_ENV_VARIABLE] PRG_NAME = "phylogenies_decorator" - PRG_DATE = "170427" + PRG_DATE = "170428" PRG_DESC = "decoration of phylogenies with sequence/species names and domain architectures" - PRG_VERSION = "1.04" + PRG_VERSION = "1.05" WWW = "https://sites.google.com/site/cmzmasek/home/software/forester" HELP_OPTION_1 = "help" @@ -86,7 +85,7 @@ module Evoruby exit( 0 ) end - if ( cla.get_number_of_files != 2 ) + if ( cla.get_number_of_files != 2 && cla.get_number_of_files != 3 ) print_help exit( -1 ) end @@ -124,30 +123,54 @@ module Evoruby verbose = true end - if File.exist?( LOG_FILE ) + if File.exist? LOG_FILE Util.fatal_error( PRG_NAME, 'logfile [' + LOG_FILE + '] already exists' ) end in_suffix = cla.get_file_name( 0 ) out_suffix = cla.get_file_name( 1 ) + mapping_files_dir = nil + + if cla.get_number_of_files == 3 + mapping_files_dir = cla.get_file_name( 2 ) + else + mapping_files_dir = Dir.getwd + end + unless File.exist? mapping_files_dir + Util.fatal_error( PRG_NAME, 'mapping files directory [' + mapping_files_dir + '] does not exist' ) + end + unless File.directory? mapping_files_dir + Util.fatal_error( PRG_NAME, '[' + mapping_files_dir + '] is not a directory' ) + end + if Dir.entries(mapping_files_dir).length <= 2 + Util.fatal_error( PRG_NAME, 'mapping files directory [' + mapping_files_dir + '] is empty' ) + end + + mapping_files_dir = Util.canonical_path( mapping_files_dir.to_s ) + log = String.new now = DateTime.now log << "Program : " + PRG_NAME + NL log << "Version : " + PRG_VERSION + NL log << "Program date : " + PRG_DATE + NL + log << "Input/Output dir : " + Dir.getwd + NL + log << "Mappings file dir : " + mapping_files_dir + NL + log << "Input suffix : " + in_suffix + NL + log << "Output suffix : " + out_suffix + NL log << "No domains data : " + no_domains.to_s + NL log << "No mol seq data : " + no_seqs_files.to_s + NL log << "Extract tax codes : " + extr_bracketed_tc.to_s + NL - log << "Date/time: " + now.to_s + NL - log << "Directory: " + Dir.getwd + NL + NL - - Util.print_message( PRG_NAME, 'input suffix : ' + in_suffix ) - Util.print_message( PRG_NAME, 'output suffix : ' + out_suffix ) + log << "Date/time: " + now.to_s + NL + NL - log << 'input suffix : ' + in_suffix + NL - log << 'output suffix : ' + out_suffix + NL + Util.print_message( PRG_NAME, 'Input/Output dir : ' + Dir.getwd ) + Util.print_message( PRG_NAME, 'Mappings file dir: ' + mapping_files_dir ) + Util.print_message( PRG_NAME, 'Input suffix : ' + in_suffix ) + Util.print_message( PRG_NAME, 'Output suffix : ' + out_suffix ) + Util.print_message( PRG_NAME, 'No domains data : ' + no_domains.to_s ) + Util.print_message( PRG_NAME, 'No mol seq data : ' + no_seqs_files.to_s ) + Util.print_message( PRG_NAME, 'Extract tax codes: ' + extr_bracketed_tc.to_s ) if ( File.exist?( TMP_FILE_1 ) ) File.delete( TMP_FILE_1 ) @@ -169,7 +192,7 @@ module Evoruby begin Util.check_file_for_readability( phylogeny_file ) rescue ArgumentError - Util.fatal_error( PRG_NAME, 'can not read from: ' + phylogeny_file + ': '+ $! ) + Util.fatal_error( PRG_NAME, 'can not read from: ' + phylogeny_file + ': '+ $!.to_s ) end counter += 1 @@ -194,7 +217,7 @@ module Evoruby Util.print_message( PRG_NAME, counter.to_s + ': ' + phylogeny_file + ' -> ' + outfile ) log << counter.to_s + ': ' + phylogeny_file + ' -> ' + outfile + NL - phylogeny_id = get_id( phylogeny_file ) + phylogeny_id = phylogeny_file if phylogeny_id == nil || phylogeny_id.size < 1 Util.fatal_error( PRG_NAME, 'could not get id from ' + phylogeny_file.to_s ) end @@ -203,75 +226,80 @@ module Evoruby end log << "Id: " + phylogeny_id + NL - ids_mapfile_name = nil - domains_mapfile_name = nil - seqs_file_name = nil + ids_mapfile_path = nil + domains_mapfile_path = nil + seqs_file_path = nil - ids_mapfile_name = get_file( ".", phylogeny_id, Constants::ID_MAP_FILE_SUFFIX ) + ids_mapfile_name = get_file( mapping_files_dir, phylogeny_id, Constants::ID_MAP_FILE_SUFFIX ) + ids_mapfile_path = Util.canonical_path(mapping_files_dir, ids_mapfile_name) begin - Util.check_file_for_readability( ids_mapfile_name ) + Util.check_file_for_readability( ids_mapfile_path) rescue IOError - Util.fatal_error( PRG_NAME, 'failed to read from [#{ids_mapfile_name}]: ' + $! ) + Util.fatal_error( PRG_NAME, "failed to read from [#{ids_mapfile_path}]: " + $!.to_s ) end if verbose - Util.print_message( PRG_NAME, "Ids mapfile: " + ids_mapfile_name ) + Util.print_message( PRG_NAME, "Ids mapfile: " + ids_mapfile_path ) end - log << "Ids mapfile: " + ids_mapfile_name + NL + log << "Ids mapfile: " + ids_mapfile_path + NL unless no_seqs_files - seqs_file_name = get_file( ".", phylogeny_id, Constants::ID_NORMALIZED_FASTA_FILE_SUFFIX ) + seqs_file_name = get_file( mapping_files_dir, phylogeny_id, Constants::ID_NORMALIZED_FASTA_FILE_SUFFIX ) + seqs_file_path = Util.canonical_path(mapping_files_dir, seqs_file_name) begin - Util.check_file_for_readability( seqs_file_name ) + Util.check_file_for_readability( seqs_file_path ) rescue IOError - Util.fatal_error( PRG_NAME, 'failed to read from [#{seqs_file_name }]: ' + $! ) + Util.fatal_error( PRG_NAME, "failed to read from [#{seqs_file_path}]: " + $!.to_s ) end if verbose - Util.print_message( PRG_NAME, "Seq file: " + seqs_file_name ) + Util.print_message( PRG_NAME, "Seq file: " + seqs_file_path ) end - log << "Seq file: " + seqs_file_name + NL + log << "Seq file: " + seqs_file_path + NL end unless no_domains - domains_mapfile_name = get_file( ".", phylogeny_id, Constants::DOMAINS_TO_FORESTER_OUTFILE_SUFFIX ) + domains_mapfile_name = get_file( mapping_files_dir , phylogeny_id, Constants::DOMAINS_TO_FORESTER_OUTFILE_SUFFIX ) + domains_mapfile_path = Util.canonical_path(mapping_files_dir, domains_mapfile_name) begin - Util.check_file_for_readability( domains_mapfile_name ) + Util.check_file_for_readability( domains_mapfile_path ) rescue IOError - Util.fatal_error( PRG_NAME, 'failed to read from [#{domains_mapfile_name}]: ' + $! ) + Util.fatal_error( PRG_NAME, "failed to read from [#{domains_mapfile_path}]: " + $!.to_s ) end if verbose - Util.print_message( PRG_NAME, "Domains file: " + domains_mapfile_name ) + Util.print_message( PRG_NAME, "Domains file: " + domains_mapfile_path ) end - log << "Domains file: " + domains_mapfile_name + NL + log << "Domains file: " + domains_mapfile_path + NL end + log << NL + NL + if no_seqs_files FileUtils.cp(phylogeny_file, TMP_FILE_1) else cmd = decorator + ' -t -p -f=m ' + phylogeny_file + ' ' + - seqs_file_name + ' ' + TMP_FILE_1 + seqs_file_path + ' ' + TMP_FILE_1 if verbose puts cmd end begin execute_cmd( cmd, log ) - rescue Error - Util.fatal_error( PRG_NAME, 'error: ' + $! ) + rescue Exception + Util.fatal_error( PRG_NAME, 'error: ' + $!.to_s ) end end unless no_domains cmd = decorator + ' ' + DECORATOR_OPTIONS_DOMAINS + ' ' + '-f=d ' + TMP_FILE_1 + ' ' + - domains_mapfile_name + ' ' + TMP_FILE_2 + domains_mapfile_path + ' ' + TMP_FILE_2 if verbose puts cmd end begin execute_cmd( cmd, log ) - rescue Error - Util.fatal_error( PRG_NAME, 'error: ' + $! ) + rescue Exception + Util.fatal_error( PRG_NAME, 'error: ' + $!.to_s ) end end @@ -282,26 +310,26 @@ module Evoruby if no_domains cmd = decorator + ' ' + opts + ' -f=n ' + TMP_FILE_1 + ' ' + - ids_mapfile_name + ' ' + outfile + ids_mapfile_path + ' ' + outfile if verbose puts cmd end begin execute_cmd( cmd, log ) - rescue Error - Util.fatal_error( PRG_NAME, 'error: ' + $! ) + rescue Exception + Util.fatal_error( PRG_NAME, 'error: ' + $!.to_s ) end File.delete( TMP_FILE_1 ) else cmd = decorator + ' ' + opts + ' -f=n ' + TMP_FILE_2 + ' ' + - ids_mapfile_name + ' ' + outfile + ids_mapfile_path + ' ' + outfile if verbose puts cmd end begin execute_cmd( cmd, log ) - rescue Error - Util.fatal_error( PRG_NAME, 'error: ' + $! ) + rescue Exception + Util.fatal_error( PRG_NAME, 'error: ' + $!.to_s ) end File.delete( TMP_FILE_1 ) File.delete( TMP_FILE_2 ) @@ -324,73 +352,41 @@ module Evoruby pipe.close_write log << pipe.read + NL + NL end + if $?.to_i != 0 + raise StandardError, "failed to execute " + cmd + end sleep( SLEEP_TIME ) end - def get_id( phylogeny_file_name ) - return phylogeny_file_name - #if phylogeny_file_name =~ /^(.+?_DA)_/ - # return $1 - #elsif phylogeny_file_name =~ /^(.+?)_/ - # return $1 - #end - #nil - end - def get_file( files_in_dir, phylogeny_id, suffix_pattern ) - Util.get_matching_file( files_in_dir, phylogeny_id, suffix_pattern ) - # matching_files = Util.get_matching_files( files_in_dir, phylogeny_id, suffix_pattern ) - # if matching_files.length < 1 - # Util.fatal_error( PRG_NAME, 'no file matching [' + phylogeny_id + - # '...' + suffix_pattern + '] present in current directory' ) - # end - # if matching_files.length > 1 - # Util.fatal_error( PRG_NAME, 'more than one file matching [' + - # phylogeny_id + '...' + suffix_pattern + '] present in current directory' ) - # end - # matching_files[ 0 ] - end - - def get_seq_file( files_in_dir, phylogeny_id ) - matching_files = Array.new - - files_in_dir.each { | file | - - if ( !File.directory?( file ) && - file !~ /^\./ && - file !~ /^00/ && - ( file =~ /^#{phylogeny_id}__.+\d$/ || file =~ /^#{phylogeny_id}_.*\.fasta$/ ) ) - matching_files << file - end - } - - if matching_files.length < 1 - Util.fatal_error( PRG_NAME, 'no seq file matching [' + - phylogeny_id + '_] present in current directory' ) - end - if matching_files.length > 1 - Util.fatal_error( PRG_NAME, 'more than one seq file matching [' + - phylogeny_id + '_] present in current directory' ) + begin + Util.get_matching_file( files_in_dir, phylogeny_id, suffix_pattern ) + rescue Exception + Util.fatal_error( PRG_NAME, 'error: ' + $!.to_s ) end - matching_files[ 0 ] end def print_help() puts "Usage:" puts - puts " " + PRG_NAME + ".rb " + puts " " + PRG_NAME + ".rb [options] [mapping files directory, default: current dir]" puts - puts " required files (in this dir): " + "name mappings : .nim" - puts " " + "sequences : _ni.fasta" - puts " " + "domain architectures: .dff" + puts " " + PRG_NAME + ".rb [options] " puts - puts " options: -" + NO_DOMAINS_OPTION + ": to not add domain architecture information (.dff file)" - puts " -" + NO_SEQS_OPTION + ": to not add molecular sequence information (_ni.fasta file)" + puts " required file (in mapping files directory): " + "name mappings : #{Constants::ID_MAP_FILE_SUFFIX}" + puts " optional files (in mapping files directory): " + "sequences : #{Constants::ID_NORMALIZED_FASTA_FILE_SUFFIX}" + puts " " + "domain architectures: #{Constants::DOMAINS_TO_FORESTER_OUTFILE_SUFFIX}" + puts + puts " options: -" + NO_DOMAINS_OPTION + ": to not add domain architecture information (#{Constants::DOMAINS_TO_FORESTER_OUTFILE_SUFFIX} file)" + puts " -" + NO_SEQS_OPTION + ": to not add molecular sequence information (#{Constants::ID_NORMALIZED_FASTA_FILE_SUFFIX} file)" puts " -" + EXTRACT_BRACKETED_TAXONOMIC_CODE_OPTION + ": to extract bracketed taxonomic codes, e.g. [NEMVE]" - puts " -" + VERBOSE_OPTION + ": verbose" + puts " -" + VERBOSE_OPTION + " : verbose" puts puts "Examples: " + PRG_NAME + ".rb .xml _d.xml" puts " " + PRG_NAME + ".rb -#{NO_DOMAINS_OPTION} -#{NO_SEQS_OPTION} .xml _d.xml" + puts " " + PRG_NAME + ".rb -#{NO_DOMAINS_OPTION} -#{NO_SEQS_OPTION} .xml _d.xml mappings_dir" + puts + puts " " + PRG_NAME + ".rb in_trees_dir out_dir mappings_dir" puts end end # class PhylogenyiesDecorator diff --git a/forester/ruby/evoruby/lib/evo/util/util.rb b/forester/ruby/evoruby/lib/evo/util/util.rb index df28bc5..7e8b554 100644 --- a/forester/ruby/evoruby/lib/evo/util/util.rb +++ b/forester/ruby/evoruby/lib/evo/util/util.rb @@ -6,10 +6,25 @@ # # Last modified: 2017/04/27 +require 'pathname' require 'lib/evo/util/constants' module Evoruby class Util + def Util.canonical_path( parent, child = nil ) + if child == nil + return File.expand_path(Pathname.new(parent).cleanpath.to_s).to_s + end + + s = nil + if parent.end_with?('/') + s = parent + child + else + s = parent + '/' + child + end + File.expand_path(Pathname.new(s).cleanpath.to_s).to_s + end + def Util.get_matching_files( files, prefix_pattern, suffix_pattern ) matching_files = Array.new files.each { | file | @@ -48,7 +63,7 @@ module Evoruby the_one = nil; loop do - puts my_prefix #TODO remove me + matches = 0 matching_files.each { | file | if file.start_with?( my_prefix ) @@ -68,8 +83,7 @@ module Evoruby done = true else if my_prefix.length <= 1 - raise IOError, "no file matching \"" + removeFileExtension( prefix ) - + "\" and ending with \"" + suffix + "\" found in [" + dir_name + "]" + raise IOError, "no file matching \"" + prefix + "\" and ending with \"" + suffix + "\" found in [" + dir_name + "]" end my_prefix = my_prefix[ 0 ... ( my_prefix.length - 1 ) ]