[I18n-sig] Sourceforge Project now operational

M.-A. Lemburg mal@lemburg.com
Thu, 02 Nov 2000 17:55:43 +0100


This is a multi-part message in MIME format.
--------------2001D64181E22032F79F61C2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Andy Robinson wrote:
> 
> Now for the big problem:  CVS tree structure.  We can have
> multiple projects under our account.  These should be named with
> some thought as each will naturally correspond to some future
> Python package.  In addition, several people are new to CVS, and
> I know I did some things wrong in the first few days.  I have put
> the two packages so far into a "practicecodecs" project into
> which people can check in anything, while we do a little planning
> on the main package.  This can be browsed on the web at
> 
> http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/?cvsroot=python-cod
> ecs
> 
> To pull these down
>   set CVSROOT =
> :pserver:username@cvs.python-codecs.sourceforge.net:/cvsroot/pyth
> on-codecs
>   cvs checkout practicecodecs
> 
> ...and end up with...
> 
>   C:\code\practicecodecs
>   C:\code\practicecodecs\JapaneseCodecs...
>   C:\code\practicecodecs\ChineseCodecs...
> 
> Anyone else wishing to check in and share bits of code should
> check this out, then add a new directory of their own under the
> top level.  Just don't start new top-level projects until
> everyone on the SIG is agreed.
> 
> Meanwhile, what are we aiming for in the long run?  Is it ONE
> add-on package with most of the world's codecs?  Or several?  If
> one, do we just call it python-codecs, and if several, what's a
> good naming convention?

As long as we end up with some working codecs I don't really
care ;-)

I think that a package AsianCodecs might be a good starter
for all encodings of that area. 

If I find time, I'll start a project for wrapping
iconv() (which is available in the C lib
on some platforms and provides access to a fairly complete
set of codecs) in a new iconvCodecs package.

BTW, I've attached a script which simplifies CVS checkins
somewhat... this should make the intial CVS exprience somewhat
more bareable ;-)

-- 
Marc-Andre Lemburg
______________________________________________________________________
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/
--------------2001D64181E22032F79F61C2
Content-Type: text/python; charset=us-ascii;
 name="checkin.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="checkin.py"

#!/usr/local/bin/python -u
"""
    Tools for (interactive) CVS checkins.

    Copyright (c) 2000, Marc-Andre Lemburg, mal@lemburg.com;

                         All Rights Reserved.

    Permission to use, copy, modify, and distribute this software and its
    documentation for any purpose and without fee or royalty is hereby granted,
    provided that the above copyright notice appear in all copies and that
    both that copyright notice and this permission notice appear in
    supporting documentation or portions thereof, including modifications,
    that you make.

    THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO
    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !

"""#"

import string,os,exceptions,tempfile,sys

__version__ = '0.4'

### Configuration

# CVS Options which will always be used
CVSOPTIONS = '-z3'

# Path of the cvs tool
CVS = "/usr/bin/cvs"

# Default name of patch editor
default_editor = 'Marc-Andre Lemburg'
default_email = 'mal@lemburg.com'

# Check the settings
if not os.path.exists(CVS):
    CVS = 'cvs'

# Debug ?
__debug__ = 0

### Errors

class CVSError(exceptions.StandardError):
    pass

### Low Level interface

def cvs(command, flags=(), files=(), options=(), test=0):

    if options:
        options = '-' + string.join(options, ' -')
    else:
        options = ''
    if flags:
        flags = '-' + string.join(flags, ' -')
    else:
        flags = ''
    cmd = '%s %s %s %s %s %s' % (CVS,
                                 CVSOPTIONS,
                                 options,
                                 command,
                                 flags,
                                 string.join(files, ' '))
    if test:
        print '* exec "%s"' % cmd
        return ''
    try:
        p = os.popen(cmd)
    except os.error,why:
        raise CVSError, why
    return p.read()

class CVSFileState:

    """ Container for CVS file update information.
    """
    new = ()
    added = ()
    modified = ()
    updated = ()
    patched = ()

    def __init__(self):

        self.new = []
        self.added = []
        self.modified = []
        self.updated = []
        self.patched = []

    def parse(self, line):

        if not line:
            return
        try:
            marker, filename = string.split(line)
        except ValueError:
            if __debug__:
                print '* could not parse: "%s"' % line
            return
        if marker == '?':
            list = self.new
        elif marker == 'M':
            list = self.modified
        elif marker == 'U':
            list = self.updated
        elif marker == 'P':
            list = self.patched
        elif marker == 'A':
            list = self.added
        else:
            if __debug__:
                print '* unkown marker: "%s" for file "%s"' % \
                      (marker, filename)
            return
        list.append(filename)

    def print_report(self, repository_only=0, workdir_only=0):

        if not repository_only:
            if self.new:
                print 'New in work dir:'
                for filename in self.new:
                    print '  ',filename
            if self.added:
                print 'Added to repository, but not yet committed:'
                for filename in self.added:
                    print '  ',filename
            if self.modified:
                print 'Modified in work dir:'
                for filename in self.modified:
                    print '  ',filename
        if not workdir_only:
            if self.updated:
                print 'Updated in repository:'
                for filename in self.updated:
                    print '  ',filename
            if self.patched:
                print 'Patched in repository:'
                for filename in p:
                    print '  ',filename

def check_files(files=('.',), modify=0):

    options = options=('q',)
    if not modify:
        options = options + ('n',)
    output = cvs('update', files=files, options=options)
    lines = string.split(output, '\n')
    files = CVSFileState()
    for line in lines:
        files.parse(line)
    return files

def update_files(files=('.',), verbose=0):

    return check_files(files, modify=1)

def checkin_files(files, message='', rev=''):

    options = ('Q',)
    flags = ()
    if message:
        tempname = tempfile.mktemp()
        open(tempname, 'w').write(message)
        flags = flags + ('F %s' % tempname,)
    else:
        tempname = ''
    if rev:
        flags = flags + ('r %s' % rev,)
    try:
        if not __debug__:
            output = cvs('commit', files=files, options=options, flags=flags)
        else:
            output = cvs('commit', files=files, options=options, flags=flags,
                         test=1)
            print message
        if output:
            if __debug__:
                print '* commit output:'
                print output
    finally:
        os.unlink(tempname)

def checkin_file(file, message='', rev=''):

    return checkin_files((file,), message, rev)
    
def add_files(files):

    if not __debug__:
        output = cvs('add', files=files, options=('Q',))
    else:
        output = cvs('add', files=files, options=('Q',), test=1)
    if output:
        if __debug__:
            print '* add output:'
            print output

def add_file(file):

    return add_files((file,))

def remove_files(files, fromdisk=0):

    if fromdisk:
        for file in files:
            try:
                os.remove(file)
            except:
                print '* could not remove file "%s"' % file
    if not __debug__:
        output = cvs('remove', files=files, options=('Q',))
    else:
        output = cvs('remove', files=files, options=('Q',), test=1)
    if output:
        if __debug__:
            print '* remove output:'
            print output

def remove_file(file):

    return remove_files((file,))

def multiline_input(prompt='', term='.', linesep='\n'):

    lines = []
    while 1:
        line = raw_input(prompt)
        if not lines and \
           not line:
            return ''
        if line == term or \
           lines and lines[-1] == line:
            return string.join(lines, linesep)
        lines.append(line)

def format_message(message, editor='', email=''):

    if email:
        header = '%s <%s>:\n' % (editor, email)
    elif editor:
        header = '%s:\n' % (editor)
    else:
        header = ''
    msg = header + message
    return string.strip(msg)
    
if __name__ == '__main__':

    # -f cmd line switch
    if '-f' in sys.argv:
        force = 1
    else:
        force = 0

    # -u cmd line switch
    if '-u' in sys.argv:
        update = 1
    else:
        update = 0

    print '='*72
    print 'CVS Checkin Utility'
    print '-'*72
    print
    if not update:
        print 'Checking work dir...',
        files = check_files()
    else:
        print 'Checking and updating work dir...',
        files = update_files()
    if files.updated or files.patched:
        if force:
            print '* WARNING:'
        print
        print '* Files changed in the repository since the last update.'
        print '* Please update before proceeding with the checkin or run'
        print '* this script with switch -f.'
        print
        print 'For your information, these files were found to be out'
        print 'of sync:'
        print
        files.print_report(repository_only=1)
        if not force:
            sys.exit(1)
    print 'done.'
    print
    if not files.new and not files.modified:
        print '* No files need to be checked in.'
        print
        sys.exit(1)

    print 'These files will be checked in:'
    print
    files.print_report(workdir_only=1)

    if 0:
        print
        print '='*72
        print 'Please enter the name and email of the patch editor:'
        print
        editor = raw_input('Name: [%s] ' % default_editor) or default_editor
        email = raw_input('EMail: [%s] ' % default_email) or default_email
    else:
        editor = ''
        email = ''

    print
    print '='*72
    print 'Please enter the commit messages for each file below...'
    print
    print '[Emtpy entries will be skipped, comments must be terminated by'
    print ' a line containing a single dot or two consecutive empty lines]'

    if files.new:
        print
        print '# New Files:'
        for file in files.new:
            print
            print '%s' % file
            print '-'*72
            message = multiline_input(term='.')
            print '-'*72
            if not message:
                print '>>> (commit skipped)'
                continue
            print '>>> Adding to CVS Repository...',
            message = format_message(message, editor, email)
            add_file(file)
            try:
                checkin_file(file, message)
            except:
                print
                print '>>> Removing file from repository due to...'
                print '    Error: %s:%s' % (sys.exc_info()[:2])
                remove_file(file)
            print 'done.'

    if files.modified:
        print
        print '# Modified Files:'
        for file in files.modified:
            print
            print '%s' % file
            print '-'*72
            message = multiline_input(term='.')
            print '-'*72
            if not message:
                print '>>> (commit skipped)'
                continue
            print '>>> Committing to CVS Repository...',
            message = format_message(message, editor, email)
            checkin_file(file, message)
            print 'done.'

    print
    print 'Done. Thanks :-)'

--------------2001D64181E22032F79F61C2--