#! /usr/bin/env python
"""This program is designed to check if a tool that is advertised as supporting
NEXUS will accept a file without an error.
Initially this is judged simply by the exit code of the process."""
import sys
import os
from read_properties import Properties
from xml.sax.saxutils import escape as xml_escape
from xml.sax.saxutils import quoteattr as xml_quoteattr
g_known_tools = ["cipres_nexus_check", "paup", "mb", "mesquite", "bio_nexus"]
g_user_prop_file = ""
class ToolInfo:
def __init__(self, name, version, path):
self.name = name
self.version = version
self.path = path
self.reset_run_info()
def reset_run_info(self):
self.return_code = None
self.stdout = ""
self.stderr = ""
self.running_time = 0.0
def name_version(self):
if self.version:
return "%s (version %s)" % (self.name, self.version)
return "%s (version unknown)" % self.name
def __str__(self):
return "%s at %s" % (self.name_version(), self.path)
def to_xml(self):
version = self.version or "?"
pref = ""
s = "ret_code=%s run_time=%s>%s%s" % (
xml_quoteattr(str(self.return_code)),
xml_quoteattr(str(self.running_time)),
xml_escape(self.stdout),
xml_escape(self.stderr))
return pref + s
def get_short_name_version(self):
if self.version:
return "%s-%s" % (self.name, self.version)
return self.name
prop_name = property(get_short_name_version)
def write_tool_list(tool_info, out):
for k in g_known_tools:
v = tool_info.get(k)
if v:
m = "%s:\n %s\n" % (k, "\n ".join([str(i) for i in v]))
out.write(m)
def read_tool_info(script_dir, script_name, warn=True):
global g_user_prop_file
p = Properties()
tried = []
prop_file = os.path.join(script_dir, "tool.properties")
if not os.path.exists(prop_file):
tried.append(prop_file)
prop_file = os.path.join(script_dir, ".nexus_tool_check_rc")
if not os.path.exists(prop_file):
tried.append(prop_file)
from user import home
prop_file = os.path.join(home, ".nexus_tool_check_rc")
if not os.path.exists(prop_file):
tried.append(prop_file)
if warn:
readme_path = os.path.join(script_dir, "README.txt")
message = _no_prop_msg % (script_name, "\n ".join(tried), readme_path)
sys.stderr.write(message)
return []
g_user_prop_file = prop_file
p.load(open(prop_file, "rU"))
names = p.propertyNames()
tool_args = {}
for name in names:
lname = name.lower()
lname_spl = lname.split("-")
lname = lname_spl[0]
if len(lname_spl) > 1:
version = "-".join(lname_spl[1:])
else:
version = ""
if not lname in g_known_tools:
if warn:
message = "%s: The tool %s is not known\n" % (script_name, name)
sys.stderr.write(message)
else:
path = p.getProperty(name)
ti = ToolInfo(lname, version, path)
if lname in tool_args:
tool_args[lname].append(ti)
else:
tool_args[lname] = [ti]
if warn and not tool_args:
message = "%s: No recognized tools were found in %s\n" % (script_name, prop_file)
sys.stderr.write(message)
return tool_args
_no_prop_msg = """%s: Properties file not found in:\n %s
The properties file must exist in one of these locations.
It should be formatted like a Java properties file and should contain keys
that are the names of NEXUS reading tools and the path to the tools.
Not all tools are supported (warnings will be given if a tool is unrecognized.
See the %s for more information.
"""
if __name__ == '__main__':
sys.exit("This file contains routines used by other scripts. It is not intended to be run")