[Zope3-checkins] CVS: Zope3/utilities - batch-cvs-commit:1.1

Fred L. Drake, Jr. fred at zope.com
Tue Feb 24 10:46:49 EST 2004


Update of /cvs-repository/Zope3/utilities
In directory cvs.zope.org:/tmp/cvs-serv15027

Added Files:
	batch-cvs-commit 
Log Message:
batch commit script to aid with large commits; mostly written by Jim with
some enhancements by Fred


=== Added File Zope3/utilities/batch-cvs-commit ===
#! /usr/bin/env python
"""Helper script for large collections of CVS commits."""

USAGE = """
Usage:

    %(program)s [file]

Perform a set of CVS commits using the files and checkin comments
specified file file.  If file is not given or is '-', standard input
is used.

The input is a series of commit descriptions.  Each description is a
set of status lines as printed by the 'cvs up' command, consisting of
'A', 'M', and 'R' lines.  After each group of status lines, the
corresponding checkin comment should be written, separated from status
lines by blank lines.

The normal usage pattern is to generate an input file using the 'cvs
up' command:

    $ cvs up >changes

and then editing the generated file to include checkin comments.  A
short example might look like this:

    M src/pkg/foo.py
    R src/pkg/subpkg/utils.py

    Replace the foobar helper with an inline implementation; it wasn't
    used anywhere else.

    A src/helpers/fastimpl.c
    M setup.py

    Add an optimized frobnicator.

    Checkin comments can have multiple paragraphs.

    M src/app/myalgorithm.py

    Use the new optimized frobnicator to get an order of magnitude
    more speed.

This file can then be fed into %(program)s to generate three separate
commits, one for each different comment.

    $ %(program)s <changes
"""

import getopt
import os
import re
import sys
import tempfile

paragraph_sep = re.compile(r"(\n\s*)+\n")
ops = re.compile(r"^([+ARM] [^\n]+\n)+$").match
qops = re.compile(r"^([+ARM?] [^\n]+\n)+$").match

def main(argv):

    try:
        opts, args = getopt.getopt(sys.argv[1:], "h?", ["help"])
    except getopt.GetoptError, e:
        print >>sys.stderr, e
        usage(sys.stderr, 2)

    if opts:
        print __doc__.strip()
        usage(sys.stdout, 0)

    if len(args) > 1:
        print >>sys.stderr, "too many arguments"
        usage(sys.stderr, 2)
    elif argv:
        # read from stdin by default
        f = '-'
    else:
        f = argv[1]

    if f == '-':
        f = sys.stdin
    else:
        f = open(f)

    data = f.read().rstrip()

    paragraphs = [(p.strip()+'\n') for p in paragraph_sep.split(data)]

    docfilename = tempfile.mktemp()

    p = paragraphs.pop(0)
    if not ops(p):
        if qops(p):
            raise "? found in operations!"
        raise "Should start with ops", p
    doc = []
    checkins = [(p, doc)]
    for p in paragraphs:
        if ops(p):
            if not doc:
                raise "No doc for", checkins[-1][0]
            doc = []
            checkins.append((p, doc))
        else:
            if qops(p):
                raise "? found in operations!"
            doc.append(p)

    for (p, doc) in checkins:
        for l in p.strip().split('\n'):
            if l[0] == '+':
                command = 'cvs add ' + l[2:]
                print command
                os.system(command)

        files_to_commit = ' '.join([l[2:] for l in p.strip().split('\n')])

        docfile = open(docfilename, 'w')
        docfile.write('\n'.join(doc))
        docfile.close()

        command = 'cvs commit -F %s %s' % (docfilename, files_to_commit)
        print command
        os.system(command)

    os.remove(docfilename)


def usage(f, rc):
    program = os.path.basename(sys.argv[0])
    message = USAGE % {"program": program}
    print >>f, message
    sys.exit(rc)


if __name__ == '__main__':
    main(sys.argv)




More information about the Zope3-Checkins mailing list