#!/usr/bin/env ruby dev_dir = nil if _i = ARGV.index("--dev") dev_dir = ARGV[_i+1] ARGV.delete "--dev" end if dev_dir.nil? _s = nil ARGV.each_with_index do |s,i| if s.match(/^--dev(?:=(.*))?/) dev_dir = $1 _s = s next end end ARGV.delete _s if _s end if dev_dir Dir.glob(File.join(File.expand_path(dev_dir),'rbbt-*/lib')).each do |f| $LOAD_PATH.unshift f end end require 'rbbt' require 'rbbt/util/simpleopt' Log.nocolor = true if ARGV.include? "--nocolor" options = SOPT.setup <<EOF Ruby bioinformatics toolkit $ rbbt <command> <subcommand> ... -a --arg1 --arg2='value' --arg3 'another-value' --log* #{Log.color :yellow, "Log level from 0 (debug) 6 (errors)"} --log_file* #{Log.color :yellow, "Divert all Rbbt logs from STDERR to the file"} --dev* #{Log.color :yellow, "Find development libraries in the directory specified"} -cd--command_dir* #{Log.color :yellow, "Directory from where to load command scripts"} --profile #{Log.color :yellow, "Profile execution"} --nocolor #{Log.color :yellow, "Disable colored output"} --nobar #{Log.color :yellow, "Disable progress report"} --nostream #{Log.color :yellow, "Disable persistance/job streaming"} --update_persist #{Log.color :yellow, "Update persisted TSV files if source has been updated"} --locate_file #{Log.color :yellow, "Report the location of the script instead of executing it"} --dump_mem* #{Log.color :yellow, "Dump strings in memory each second into file"} -nolock--no_lock_id #{Log.color :yellow, "Do not track lockfiles with ids (prevent stale file handlers for high-througput and high-concurrency)"} EOF locate = options.delete :locate_file if options[:log_file] Log.logfile(options[:log_file]) end if options[:log] Log.severity = options[:log].to_i else global_severity = Log.get_level(Rbbt.etc.log_severity.read.strip) if Rbbt.etc.log_severity.exists? if ENV["RBBT_LOG"] Log.severity = ENV["RBBT_LOG"].to_i else global_severity = Log.get_level(Rbbt.etc.log_severity.read.strip) if Rbbt.etc.log_severity.exists? Log.severity = global_severity.to_i if global_severity end end if options.delete(:no_lock_id) Misc.use_lock_id = false end if mem_dump = options.delete(:dump_mem) require 'rbbt/monitor' Rbbt.dump_memory(mem_dump, String) end if options.delete(:update_persist) ENV["RBBT_UPDATE_TSV_PERSIST"] = "true" end if options.delete :nostream ENV["RBBT_NO_STREAM"] = "true" end if options.delete :nobar ENV["RBBT_NO_PROGRESS"] = "true" end if options[:command_dir] $rbbt_command_dir = Path.setup(options[:command_dir].dup) else $rbbt_command_dir = Rbbt.share.rbbt_commands end SOPT.description =<<EOF This command controls many aspects of the Rbbt framework, from configuration tasks to running applications. Commands are implemented in separate files under the Rbbt path '#{$rbbt_command_dir}'. Known locations are: #{([$rbbt_command_dir] + $rbbt_command_dir.find_all) * ", " }. You can place your own commads at #{$rbbt_command_dir.find(:user)}. EOF if options[:profile] require 'ruby-prof' RubyProf.start end def prev_dir(prev) rbbt_command_dir = $rbbt_command_dir prev.each do |previous_command| rbbt_command_dir = rbbt_command_dir[previous_command] end rbbt_command_dir end def commands(prev) rbbt_command_dir = prev_dir(prev) command_file_dirs = rbbt_command_dir.find_all command_files = command_file_dirs.collect{|d| d.glob('*') }.flatten command_files.collect{|p| File.basename(p) }.uniq.reject{|p| p =~ /\.desc$/}.sort end def rbbt_usage(prev = nil) puts puts SOPT.doc if prev puts puts Log.color :magenta, "## COMMANDS" puts puts Log.color :magenta, "Command:" puts puts " #{File.basename($0)} #{prev * " "}" puts puts Log.color :magenta, "Subcommands:" puts prev_dir = prev_dir(prev) commands(prev).each do |command| directory = File.directory? prev_dir[command].find if directory puts " " << Log.color(:blue, command) else puts " " << command end end end puts true end alias usage rbbt_usage def print_error(error, backtrace = nil) puts Log.color :magenta, "## ERROR" puts if backtrace puts Log.color :red, "Backtrace: " puts puts backtrace.reverse * "\n" puts end puts Log.color :red, error puts end def aliases @aliases ||= Rbbt.etc.cmd_alias.exists? ? Rbbt.etc.cmd_alias.yaml : {} end def cmd_alias while aliases.include? ARGV[0] ARGV.replace Misc.parse_cmd_params(aliases[ARGV[0]]) + ARGV[1..-1] end end dir = $rbbt_command_dir $previous_commands = [] cmd_alias begin while ARGV.any? $command = ARGV.shift case when File.directory?(dir[$command].find) $previous_commands << $command dir = dir[$command] when dir[$command].exists? if locate puts dir[$command].find exit 0 else load dir[$command].find exit 0 end when File.exists?($command) load $command exit 0 else error = "Command '#{$command }' not understood" rbbt_usage($previous_commands) print_error(error) exit -1 end end rbbt_usage($previous_commands) exit 0 rescue ParameterException puts rbbt_usage print_error($!.message, $!.backtrace) puts exit -1 rescue SystemExit rescue Exception Log.exception $! exit -1 ensure if options[:profile] result = RubyProf.stop printer = RubyProf::FlatPrinter.new(result) printer.print(STDOUT, :min_percent => 10) end end