svn hooks /

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import compiler
import sys
from subprocess import Popen
from subprocess import PIPE

checker = __import__('pyflakes.checker').checker

def check(codeString, filename):
    Check the Python source given by C{codeString} for flakes.

    @param codeString: The Python source to check.
    @type codeString: C{str}

    @param filename: The name of the file the source came from, used to report
    @type filename: C{str}

    @return: The number of warnings emitted.
    @rtype: C{int}
    # Since compiler.parse does not reliably report syntax errors, use the
    # built in compiler first to detect those.
            compile(codeString, filename, "exec")
        except MemoryError:
            # Python 2.4 will raise MemoryError if the source can't be
            # decoded.
            if sys.version_info[:2] == (2, 4):
                raise SyntaxError(None)
    except (SyntaxError, IndentationError), value:
        msg = value.args[0]

        (lineno, offset, text) = value.lineno, value.offset, value.text

        # If there's an encoding problem with the file, the text is None.
        if text is None:
            # Avoid using msg, since for the only known case, it contains a
            # bogus message that claims the encoding the file declared was
            # unknown.
            return ["%s: problem decoding source" % (filename, )]
            line = text.splitlines()[-1]

            if offset is not None:
                offset = offset - (len(text) - len(line))

            return ['%s:%d: %s' % (filename, lineno, msg)]

        return []
        # Okay, it's syntactically valid.  Now parse it into an ast and check
        # it.
        tree = compiler.parse(codeString)
        w = checker.Checker(tree, filename)
        w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
        return w.messages

def checkPath(filename, look_cmd):
        return check(file_contents(filename, look_cmd) + '\n', filename)
    except IOError, msg:
        return [msg.args[1]]

def command_output(cmd):
    """ Capture a command's standard output."""
    return Popen(cmd.split(), stdout=PIPE).communicate()[0]

def files_changed(look_cmd):
    """ List the files added or updated by this transaction."""
    def filename(line):
        return line[4:]

    def added_or_updated(line):
        return line and line[0] in ("A", "U")

    return [filename(line) for line in
            command_output(look_cmd % "changed").split("\n")
            if added_or_updated(line)]

def file_contents(filename, look_cmd):
    """Return a file's contents for this transaction"""
    return command_output("%s %s" % (look_cmd % "cat", filename))

def check_file(look_cmd):
    """checks Python files in this transaction

    erroneous_files = []
    for file in files_changed(look_cmd):
        if not file.endswith('.py'):

        # special cases
        if 'ledenadministratie' in file:

        if '/skins/' in file or '/tags/' in file or file == '':

        contents = file_contents(file, look_cmd)
        if '#IGNORE PYFLAKES' in contents:

        msgs = checkPath(file, look_cmd)
        if msgs:
            for msg in msgs:
                erroneous_files.append((msg, file))

    num_failures = len(erroneous_files)

    if num_failures > 0:
        sys.stderr.write("[ERROR pyflakes] please check your files:\n")
        for error_type, file in erroneous_files:
            sys.stderr.write("[ERROR] %s in %s\n" % (error_type, file))

    return num_failures

def main():
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-r", "--revision",
                        help="Test mode. TXN actually refers to a revision.",
                        action="store_true", default=False)
    errors = 0
    (opts, (repos, txn_or_rvn)) = parser.parse_args()
    look_opt = ("--transaction", "--revision")[opts.revision]
    look_cmd = "svnlook %s %s %s %s" % (
        "%s", repos, look_opt, txn_or_rvn)
    errors += check_file(look_cmd)

    return errors

if __name__ == "__main__":