X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/289687b4c70e165b5a4809bfcb9f8608f1b55bd3..3dccdc9bf6d5b2e72a982187f5f947b20f24fc87:/stgit/run.py diff --git a/stgit/run.py b/stgit/run.py index fa304d0..7493ed3 100644 --- a/stgit/run.py +++ b/stgit/run.py @@ -27,12 +27,40 @@ class RunException(StgException): subprocess.""" pass -_all_log_modes = ['debug', 'profile'] -_log_mode = os.environ.get('STGIT_SUBPROCESS_LOG', '') -if _log_mode and not _log_mode in _all_log_modes: - out.warn(('Unknown log mode "%s" specified in $STGIT_SUBPROCESS_LOG.' - % _log_mode), - 'Valid values are: %s' % ', '.join(_all_log_modes)) +def get_log_mode(spec): + if not ':' in spec: + spec += ':' + (log_mode, outfile) = spec.split(':', 1) + all_log_modes = ['debug', 'profile'] + if log_mode and not log_mode in all_log_modes: + out.warn(('Unknown log mode "%s" specified in $STGIT_SUBPROCESS_LOG.' + % log_mode), + 'Valid values are: %s' % ', '.join(all_log_modes)) + if outfile: + f = MessagePrinter(open(outfile, 'a')) + else: + f = out + return (log_mode, f) + +(_log_mode, _logfile) = get_log_mode(os.environ.get('STGIT_SUBPROCESS_LOG', '')) +if _log_mode == 'profile': + _log_starttime = datetime.datetime.now() + _log_subproctime = 0.0 + +def duration(t1, t2): + d = t2 - t1 + return 86400*d.days + d.seconds + 1e-6*d.microseconds + +def finish_logging(): + if _log_mode != 'profile': + return + ttime = duration(_log_starttime, datetime.datetime.now()) + rtime = ttime - _log_subproctime + _logfile.info('Total time: %1.3f s' % ttime, + 'Time spent in subprocess calls: %1.3f s (%1.1f%%)' + % (_log_subproctime, 100*_log_subproctime/ttime), + 'Remaining time: %1.3f s (%1.1f%%)' + % (rtime, 100*rtime/ttime)) class Run: exc = RunException @@ -42,21 +70,32 @@ class Run: if type(c) != str: raise Exception, 'Bad command: %r' % (cmd,) self.__good_retvals = [0] - self.__env = None + self.__env = self.__cwd = None self.__indata = None self.__discard_stderr = False def __log_start(self): if _log_mode == 'debug': - out.start('Running subprocess %s' % self.__cmd) + _logfile.start('Running subprocess %s' % self.__cmd) + if self.__cwd != None: + _logfile.info('cwd: %s' % self.__cwd) + if self.__env != None: + for k in sorted(self.__env.iterkeys()): + if k not in os.environ or os.environ[k] != self.__env[k]: + _logfile.info('%s: %s' % (k, self.__env[k])) elif _log_mode == 'profile': - out.start('Running subprocess %s' % self.__cmd[0]) + _logfile.start('Running subprocess %s' % self.__cmd) self.__starttime = datetime.datetime.now() def __log_end(self, retcode): + global _log_subproctime, _log_starttime if _log_mode == 'debug': - out.done('return code: %d' % retcode) + _logfile.done('return code: %d' % retcode) elif _log_mode == 'profile': - duration = datetime.datetime.now() - self.__starttime - out.done('%1.3f s' % (duration.microseconds/1e6 + duration.seconds)) + n = datetime.datetime.now() + d = duration(self.__starttime, n) + _logfile.done('%1.3f s' % d) + _log_subproctime += d + _logfile.info('Time since program start: %1.3f s' + % duration(_log_starttime, n)) def __check_exitcode(self): if self.__good_retvals == None: return @@ -67,7 +106,7 @@ class Run: """Run with captured IO.""" self.__log_start() try: - p = subprocess.Popen(self.__cmd, env = self.__env, + p = subprocess.Popen(self.__cmd, env = self.__env, cwd = self.__cwd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE) @@ -85,7 +124,7 @@ class Run: assert self.__indata == None self.__log_start() try: - p = subprocess.Popen(self.__cmd, env = self.__env) + p = subprocess.Popen(self.__cmd, env = self.__env, cwd = self.__cwd) self.exitcode = p.wait() except OSError, e: raise self.exc('%s failed: %s' % (self.__cmd[0], e)) @@ -104,12 +143,18 @@ class Run: self.__env = dict(os.environ) self.__env.update(env) return self + def cwd(self, cwd): + self.__cwd = cwd + return self def raw_input(self, indata): self.__indata = indata return self def input_lines(self, lines): self.__indata = ''.join(['%s\n' % line for line in lines]) return self + def input_nulterm(self, lines): + self.__indata = ''.join('%s\0' % line for line in lines) + return self def no_output(self): outdata = self.__run_io() if outdata: