<commit_before>import sys
import os
import shutil


class Command(object):

    def __init__(self):
        pass

    def execute(self):
        self._execute()

    def _execute(self):
        raise NotImplemented

class UndoableCommand(Command):

    def __init__(self):
        Command.__init__(self)

    def execute(self):
        try:
            return self._execute()
        except Exception:
            self.undo()
            exc_info = sys.exc_info()
            raise exc_info[1], None, exc_info[2]

    def _execute(self):
        raise NotImplemented()

    def undo(self):
        raise NotImplemented

    def cleanup(self):
        raise NotImplemented


class CompoundCommand(UndoableCommand):
    # TODO: this should really be an UndoableCommand
    # TODO: keep track of which commands completed successfully so that we can undo them if needs be

    def __init__(self, *args):
        self.commands = args
        self.executed_commands = []

    def _execute(self):
        for cmd in self.commands:
            print cmd
            cmd.execute()
            self.executed_commands.append(cmd)
        self.cleanup()

    def undo(self):
        print "undo: %s" % self.executed_commands
        while len(self.executed_commands):
            cmd = self.executed_commands.pop()
            if not isinstance(cmd, UndoableCommand):
                continue
            print "undoing %s" % cmd
            cmd.undo()

    def cleanup(self):
        while len(self.executed_commands):
            cmd = self.executed_commands.pop()
            print "cleaning up %s" % cmd
            cmd.cleanup()

    def push(self, command):
        self.commands.append(command)


class NotAFileException(BaseException):
    pass


class CopyFileCommand(Command):

    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
        if not os.path.isfile(src):
            raise NotAFileException()

    def _execute(self):
        print "CopyFileCommand(%s, %s)" % (self.src, self.dest)
        shutil.copy2(self.src, self.dest)


class MoveFileCommand(UndoableCommand):

    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
        if not os.path.isfile(src):
            raise NotAFileException()

    def _execute(self):
        print "MoveFileCommand(%s, %s)" % (self.src, self.dest)
        # TODO: check for existance of dest and maybe abort? As it is, this
        # will automatically overwrite.
        shutil.move(self.src, self.dest)

    def undo(self):
        # TODO: perhaps check to see that the file was moved cleanly?
        shutil.move(self.dest, self.src)


class SafeMoveFileCommand(MoveFileCommand):

    def __init__(self, src, dest, backupfile_dir=None):
        MoveFileCommand.__init__(self, src, dest)
        if not backupfile_dir:
            self.backupfile_dir = os.path.dirname(self.src)
        else:
            self.backupfile_dir = backupfile_dir

    def _execute(self):
        self.backup_filename = os.path.join(self.backupfile_dir, "._tmp_." + os.path.basename(self.src))
        # keep a copy of the files locally
        self.copy_cmd = CopyFileCommand(self.src, self.backup_filename)
        self.copy_cmd.execute()
        # move the file
        MoveFileCommand._execute(self)

    def undo(self):
        shutil.move(self.backup_filename, self.src)
        os.remove(self.dest)

    def cleanup(self):
        # remove the local copy
        os.remove(self.backup_filename)


class LinkToFileCommand(Command):

    def __init__(self, linkname, targetname):
        self.linkname = linkname
        self.targetname = targetname

    def _execute(self):
        os.symlink(self.targetname, self.linkname)


class ChmodCommand(UndoableCommand):

    def __init__(self, modes, filename):
        self.modes = modes
        self.filename = filename
        self.previous_modes = 0

    def _execute(self):
        print "ChmodCommand(%s, %o)" % (self.filename, self.modes)
        self.previous_modes = os.stat(self.filename).st_mode
        print "previous: %o" % self.previous_modes
        os.chmod(self.filename, self.modes)

    def undo(self):
        # TODO: it's conceivable that the modes were set and the user no longer
        # has permission to modify the modes. Not sure what to do in that case.
        os.chmod(self.filename, self.previous_modes)


class MakeDirectoryCommand(Command):

    def __init__(self, dirname, modes=0777):
        self.dirname, self.modes = dirname, modes

    def _execute(self):
        print "MakeDirectory(%s, %o)" % (self.dirname, self.modes)
        if not os.path.exists(self.dirname):
            os.makedirs(self.dirname, self.modes)

class GitAddCommand(UndoableCommand):

    def __init__(self, gitrepo, filename):
        self.gitrepo = gitrepo
        self.filename = filename

    def _execute(self):
        self.gitrepo.index.add(self.filename)

    def undo(self):
        self.gitrepo.index.remove(self.filename)
<commit_msg>working git-bin-add<commit_after>import sys
import os
import shutil


class Command(object):

    def __init__(self):
        pass

    def execute(self):
        self._execute()

    def _execute(self):
        raise NotImplemented

    def __repr__(self):
        return object.__repr__(self)


class UndoableCommand(Command):

    def __init__(self):
        Command.__init__(self)

    def execute(self):
        try:
            return self._execute()
        except Exception:
            self.undo()
            exc_info = sys.exc_info()
            raise exc_info[1], None, exc_info[2]

    def _execute(self):
        raise NotImplemented()

    def undo(self):
        raise NotImplemented

    def cleanup(self):
        pass


class CompoundCommand(UndoableCommand):
    # TODO: this should really be an UndoableCommand
    # TODO: keep track of which commands completed successfully so that we can undo them if needs be

    def __init__(self, *args):
        self.commands = args
        self.executed_commands = []

    def _execute(self):
        for cmd in self.commands:
            print cmd
            cmd.execute()
            self.executed_commands.append(cmd)
        self.cleanup()

    def undo(self):
        print "undo: %s" % self.executed_commands
        while len(self.executed_commands):
            cmd = self.executed_commands.pop()
            if not isinstance(cmd, UndoableCommand):
                continue
            print "undoing %s" % cmd
            try:
                cmd.undo()
            except Exception:
                print "\nException while undoing %s" % cmd
                import traceback
                traceback.print_exc()
                print "Continuing to undo other commands ...\n"

    def cleanup(self):
        while len(self.executed_commands):
            cmd = self.executed_commands.pop()
            if not isinstance(cmd, UndoableCommand):
                continue
            print "cleaning up %s" % cmd
            cmd.cleanup()

    def push(self, command):
        self.commands.append(command)


class NotAFileException(BaseException):
    pass


class CopyFileCommand(Command):

    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
        if not os.path.isfile(src):
            raise NotAFileException()

    def _execute(self):
        shutil.copy2(self.src, self.dest)

    def __repr__(self):
        return "%s(%s, %s)" % (self.__class__.__name__, self.src, self.dest)


class MoveFileCommand(UndoableCommand):

    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
        if not os.path.isfile(src):
            raise NotAFileException()

    def _execute(self):
        # TODO: check for existance of dest and maybe abort? As it is, this
        # will automatically overwrite.
        shutil.move(self.src, self.dest)

    def undo(self):
        # TODO: perhaps check to see that the file was moved cleanly?
        shutil.move(self.dest, self.src)

    def __repr__(self):
        return "%s(%s, %s)" % (self.__class__.__name__, self.src, self.dest)


class SafeMoveFileCommand(MoveFileCommand):

    def __init__(self, src, dest, backupfile_dir=None):
        MoveFileCommand.__init__(self, src, dest)
        if not backupfile_dir:
            self.backupfile_dir = os.path.dirname(self.src)
        else:
            self.backupfile_dir = backupfile_dir

    def _execute(self):
        self.backup_filename = os.path.join(self.backupfile_dir, "._tmp_." + os.path.basename(self.src))
        # keep a copy of the files locally
        self.copy_cmd = CopyFileCommand(self.src, self.backup_filename)
        self.copy_cmd.execute()
        # move the file
        MoveFileCommand._execute(self)

    def undo(self):
        shutil.move(self.backup_filename, self.src)
        os.remove(self.dest)

    def cleanup(self):
        # remove the local copy
        os.remove(self.backup_filename)


class LinkToFileCommand(Command):

    def __init__(self, linkname, targetname):
        self.linkname = linkname
        self.targetname = targetname

    def _execute(self):
        os.symlink(self.targetname, self.linkname)

    def __repr__(self):
        return "%s(%s, %s)" % (self.__class__.__name__, self.targetname, self.linkname)


class ChmodCommand(UndoableCommand):

    def __init__(self, modes, filename):
        self.modes = modes
        self.filename = filename
        self.previous_modes = 0

    def _execute(self):
        self.previous_modes = os.stat(self.filename).st_mode
        os.chmod(self.filename, self.modes)

    def undo(self):
        # TODO: it's conceivable that the modes were set and the user no longer
        # has permission to modify the modes. Not sure what to do in that case.
        os.chmod(self.filename, self.previous_modes)

    def __repr__(self):
        return "%s(%s, %o)" % (self.__class__.__name__, self.filename, self.modes)


class MakeDirectoryCommand(Command):

    def __init__(self, dirname, modes=0777):
        self.dirname, self.modes = dirname, modes

    def _execute(self):
        if not os.path.exists(self.dirname):
            os.makedirs(self.dirname, self.modes)

    def __repr__(self):
        return "%s(%s)" % (self.__class__.__name__, self.dirname)


class GitAddCommand(UndoableCommand):

    def __init__(self, gitrepo, filename):
        self.gitrepo = gitrepo
        self.filename = filename

    def _execute(self):
        self.gitrepo.add(self.filename)

    def undo(self):
        self.gitrepo.unstage(self.filename)

    def __repr__(self):
        return "%s(%s)" % (self.__class__.__name__, self.filename)

{'fraction_non_alphanumeric': 0.09993425378040763, 'fraction_numerical': 0.0015027707335399643, 'mean_word_length': 2.3295809881175735, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3650947', 'n_tokens_mistral': 3219, 'n_tokens_neox': 3067, 'n_words': 790}