[Zope3-dev] Re: [Zope-Coders] Denying commit for carriage returns in text

Fred L. Drake, Jr. fred@zope.com
Wed, 13 Nov 2002 18:15:36 -0500


--gyM5Z+ZG9+
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit


I wrote:
 > I've attached a script that could be run from CVSROOT/commitinfo that
 > denies a commit if a text file contains a carriage return.  It ignores
 > binary files (the -kb sticky option is set).

Ok, I've now attached a Python version that also checks for Tab in
Python source files and denies those as well.  This has the distinct
advantage that it only runs one child (os.popen() might add a layer of
shell, though ;-( ), and does most of the mindless checking internally
(no more tempfile!).


  -Fred

-- 
Fred L. Drake, Jr.  <fred at zope.com>
PythonLabs at Zope Corporation


--gyM5Z+ZG9+
Content-Type: text/x-python
Content-Description: Python version of script
Content-Disposition: inline;
	filename="check-commit.py"
Content-Transfer-Encoding: 7bit

#! /usr/local/bin/python

import os.path
import sys

REPODIR = sys.argv[1]

def main():
    items = []
    files = sys.argv[2:]
    for file in files:
        rcsfile = os.path.join(REPODIR, file) + ',v'
        if os.path.isfile(file) and os.path.isfile(rcsfile):
            items.append((file, rcsfile))
    if not items:
        return 0
    rlog_cmd = "rlog -h"
    for file, rcsfile in items:
        assert "'" not in rcsfile
        rlog_cmd += " '%s'" % rcsfile
    fp = os.popen(rlog_cmd, "r")

    failures = []
    while 1:
        line = fp.readline()
        if items and not line:
            fp.close()
            print >>sys.stderr, \
                  "No more input before determining the nature of all files."
            return 1
        assert line
        parts = line.split(": ", 1)
        parts[0] = parts[0].lower()
        if parts[0] == "rcs file":
            filename = parts[-1][:-1]
            file, rcsfile = items[0]
            print "File:", `filename`
            print "RCS File:", `rcsfile`
            assert rcsfile == filename
        elif parts[0] == "keyword substitution":
            file, rcsfile = items.pop(0)
            if "b" in parts[1]:
                continue
            text = open(file, "rb").read()
            if "\r" in text:
                failures.append(file + " (contains carriage return)")
            else:
                ext = os.path.splitext(file)[1]
                if ext == ".py" and "\t" in text:
                    failures.append(file + " (contains tab in Python code)")
            if not items:
                # all done
                break

    if failures:
        print "***"
        print "*** Found disallowed characters in text file; commit denied!"
        print "***"
        for msg in failures:
            print "*** File:", msg
        print "***"
        fp.close()
        return 1
    else:
        return fp.close()

if __name__ == "__main__":
    sys.exit(main())

--gyM5Z+ZG9+--