import argparse
import logging
import os.path
import sys

from mirte.core import Manager
from mirte.mirteFile import load_mirteFile

from sarah.order import sort_by_successors
import sarah.coloredLogging

def parse_static_cmdLine(args):
        """ Uses argparse to parse the `static' commandLine options. """
        parser = argparse.ArgumentParser(
                description='Runs a Mirte module')
        parser.add_argument('-p', '--profile', dest='profile',
                metavar='FILE',
                help='Enables profiling and write to FILE')
        parser.add_argument('module', default='default', nargs='?',
                help='Module to execute')
        return parser.parse_known_args(args)

def parse_cmdLine_instructions(args):
        """ Parses remaining command-line arguments.  These are
            instruction to the manager to create instances and
            put settings. """
        instructions = dict()
        rargs = list()
        for arg in args:
                if arg[:2] == '--':
                        tmp = arg[2:]
                        bits = tmp.split('=', 1)
                        if len(bits) == 1:
                                bits.append('')
                        instructions[bits[0]] = bits[1]
                else:
                        rargs.append(arg)
        return instructions, rargs

def execute_cmdLine_instructions(instructions, m, l):
        """ Applies the instructions given via
            <instructions> on the manager <m> """
        opt_lut = dict()
        inst_lut = dict()
        for k, v in instructions.iteritems():
                bits = k.split('-', 1)
                if len(bits) == 1:
                        if not v in m.modules:
                                raise KeyError, "No such module: %s" % v
                        inst_lut[bits[0]] = v
                else:
                        if not bits[0] in opt_lut:
                                opt_lut[bits[0]] = list()
                        opt_lut[bits[0]].append((bits[1], v))
        inst_list = sort_by_successors(inst_lut.keys(),
                        lambda inst: [v for (k,v) in opt_lut.get(inst, ())
                                        if k in m.modules[inst_lut[inst]].deps])
        for k in reversed(tuple(inst_list)):
                if k in m.insts:
                        raise NotImplementedError, \
                                "Overwriting instancens not yet supported"
                settings = dict()
                if k in opt_lut:
                        for k2, v2 in opt_lut[k]:
                                settings[k2] = v2
                m.create_instance(k, inst_lut[k], settings)
        for k in opt_lut:
                if k in inst_lut:
                        continue
                for k2, v2 in opt_lut[k]:
                        if not k in m.insts:
                                raise ValueError, "No such instance %s" % k
                        m.change_setting(k, k2, v2)

class MirteFormatter(logging.Formatter):
        def __init__(self):
                pass
        def format(self, record):
                record.message = record.getMessage()
                if 'sid' in record.__dict__:
                        record.name += '.'+str(record.sid)
                ret = ("%(relativeCreated)d %(levelname)"+
                        "-8s%(name)s:%(message)s") % record.__dict__
                if record.exc_info:
                        ret += self.formatException(record.exc_info)
                return ret

def main():
        """ Entry-point """
        # There are two passes of command-line parsing.  First we use
        # argparse to parse the static command-line options, like --profile.
        # Then we use `parse_cmdLine_instructions' to handle the
        # remaining instructions to the manager, like --threadPool-maxFree=3
        options, args = parse_static_cmdLine(sys.argv[1:])
        if options.profile:
                import cProfile
                cProfile.runctx('_profiled_main(options, args)',
                                        globals(), locals(), options.profile)
        else:
                _profiled_main(options, args)

def _profiled_main(options, args):
        """ Remainder of main() that is to be profiled (if profiling is
            enabled. """
        sarah.coloredLogging.basicConfig(level=logging.DEBUG,
                                formatter=MirteFormatter())
        l = logging.getLogger('mirte')
        instructions, args = parse_cmdLine_instructions(args)
        m = Manager(l)
        load_mirteFile(options.module, m, logger=l)
        execute_cmdLine_instructions(instructions, m, l)
        m.run()

if __name__ == '__main__':
        if os.path.abspath('.') in sys.path:
                sys.path.remove(os.path.abspath('.'))
        main()

@@ -531,16 +531,28 @@
 ofiling 
+using yappi 
 and writ
@@ -3982,353 +3982,65 @@
 ort 
-cProfile%0A                cProfile.runctx('_profiled_main(options, args)',%0A                                        globals(), locals(), options.profile)%0A        else:%0A                _profiled_main(options, args)%0A%0Adef _profiled_main(options, args):%0A        %22%22%22 Remainder of main() that is to be profiled (if profiling is%0A            enabled. %22%22%22%0A
+yappi%0A                yappi.start()%0A        try:%0A        
     
@@ -4129,16 +4129,24 @@
         
+        
 formatte
@@ -4173,16 +4173,24 @@
         
+  
+      
 l = logg
@@ -4212,32 +4212,40 @@
 mirte')%0A        
+    
+    
 instructions, ar
@@ -4278,24 +4278,32 @@
 tions(args)%0A
+        
         m = 
@@ -4321,16 +4321,24 @@
         
+      
+  
 load_mir
@@ -4381,16 +4381,24 @@
         
+       
+ 
 execute_
@@ -4438,16 +4438,24 @@
 , m, l)%0A
+        
         
@@ -4462,16 +4462,230 @@
 m.run()%0A
+        finally:%0A                if options.profile:%0A                        with open(options.profile, 'w') as f:%0A                                yappi.stop()%0A                                yappi.print_stats(f)%0A%0A
 %0Aif __na

replace cProfile with yappi for profiling