Mercurial > gub
view gub/runner.py @ 5482:6b5f592edd98
Add symlink and map_find_files.
author | Jan Nieuwenhuizen <janneke@gnu.org> |
---|---|
date | Thu, 20 Aug 2009 14:36:05 +0200 |
parents | a099c209b3eb |
children | 4a71efdff50b |
line wrap: on
line source
#! /usr/bin/env python """ Copyright (c) 2005--2007 Jan Nieuwenhuizen <janneke@gnu.org> Han-Wen Nienhuys <hanwen@xs4all.nl> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """ import os import re import sys # from gub.syntax import printf from gub import misc from gub import commands class CommandRunner: '''Encapsulate OS/File system commands This enables proper logging and deferring and checksumming of commands.''' def __init__ (self, logger): self.logger = logger self.fakeroot_cmd = False def is_deferred (self): return False def _execute (self, command): return command.execute (self.logger) # fixme: should be moved somewhere else. def fakeroot (self, s): self.fakeroot_cmd = s def verbose_flag (self): return '' def system_one (self, cmd, env, ignore_errors): '''Run CMD with environment vars ENV.''' # YUK if self.fakeroot_cmd: cmd = re.sub ('''(^ *|['"();|& ]*)(fakeroot) ''', '\\1%(fakeroot_cmd)s' % self.__dict__, cmd) cmd = re.sub ('''(^ *|['"();|& ]*)(chown|rm|tar) ''', '\\1%(fakeroot_cmd)s\\2 ' % self.__dict__, cmd) # ' return self._execute (commands.System (cmd, env=env, ignore_errors=ignore_errors)) def log (self, str, logtype): return self._execute (commands.Message (str, logtype)) # fixme: repetitive code. def action (self, str): self.log (str, 'action') def stage (self, str): self.log (str, 'stage') def error (self, str): self.log (str, 'error') def info (self, str): self.log (str, 'info') def command (self, str): self.log (str, 'command') def debug (self, str): self.log (str, 'debug') def warning (self, str): self.log (str, 'warning') def harmless (self, str): self.log (str, 'harmless') def verbose (self, str): self.log (str, 'verbose') # end fixme def system (self, cmd, env={}, ignore_errors=False): '''Run os commands, and run multiple lines as multiple commands.''' call_env = os.environ.copy () call_env.update (env) self.logger.log_env (env) for i in cmd.split ('\n'): if i: self.system_one (i, call_env, ignore_errors) def dump (self, *args, **kwargs): return self._execute (commands.Dump (*args, **kwargs)) def file_sub (self, *args, **kwargs): return self._execute (commands.Substitute (*args, **kwargs)) def shadow_tree (self, src, target, soft=False): return self._execute (commands.ShadowTree (src, target, soft)) def map_find_files (self, func, directory, pattern, must_happen=False, silent=False, find_func=misc.find_files): return self._execute (commands.MapLocate (func, directory, pattern, must_happen, silent, find_func)) def map_locate (self, func, directory, pattern, must_happen=False, silent=False, find_func=misc.locate_files): return self._execute (commands.MapLocate (func, directory, pattern, must_happen, silent, find_func)) def copy (self, src, dest): return self._execute (commands.Copy (src, dest)) def link (self, src, dest): return self._execute (commands.Link (src, dest)) def symlink (self, src, dest): return self._execute (commands.Symlink (src, dest)) def rename (self, src, dest): return self._execute (commands.Rename (src, dest)) def func (self, f, *args): return self._execute (commands.Func (f, *args)) def mkdir (self, dir): return self._execute (commands.Mkdir (dir)) def chmod (self, file, mode): return self._execute (commands.Chmod (file, mode)) def remove (self, file): return self._execute (commands.Remove (file)) def rmtree (self, file, ignore_errors=False): return self._execute (commands.Rmtree (file, ignore_errors)) def first_is_newer (self, first, second): return misc.first_is_newer (first, second) def pred_if_else (self, predicate, true, false=None): return self._execute (commands.Conditional (predicate, true, false)) class DeferredRunner (CommandRunner): def __init__ (self, *args): CommandRunner.__init__ (self, *args) self._deferred_commands = list () def is_deferred (self): return True def execute_deferred_commands (self): commands = self._deferred_commands self._deferred_commands = [] for cmd in commands: cmd.execute (self.logger) if self._deferred_commands: printf ('*** deferred leftovers:', self._deferred_commands) assert self._deferred_commands == list () def flush_deferred_commands (self): self._deferred_commands = list () def checksum (self): # we use a visitor pattern, to shield SerializedCommand from # the actual type of the checksum (md5 hasher, list, etc.); If # we use return values, composite SerializedCommand # (eg. Conditional) have to be aware of the type to combine # results for their children. result = [] if sys.version.startswith ('3'): def str_append (x): result.append (str (x)) map (lambda x: x.checksum (str_append), self._deferred_commands) else: list (map (lambda x: x.checksum (result.append), self._deferred_commands)) return '\n'.join (result) def _execute (self, command): self._deferred_commands.append (command)