#!/usr/bin/env python
# Convert the result of paster create --template pylons {pkg-name}
# to be a subpackage so that you can use it in an existing project
# TODO: fix up test/__init__.py
# 
# Alternative approach is just to mess around with paster
# See e.g.
# http://docs.pythonweb.org/display/pylonscookbook/Creating+Templates+For+The+paster+create+Command
#
# My own experiments show that things like:
# 
# paster create -t pylons . project=Blah package=mypkg.jones egg=blah 
# paster create -t pylons testpaster/abc project=Blah package=mypkg.jones egg=blah template_engine=genshi
#
# create standard setup but with no extra directory at top (so useful for
# creating in trunk of a svn layout).
# paster create -t pylons . project=microfacts package=microfacts egg=microfacts template_engine=genshi
#
# work fairly well at overwriting existing values.
# 
# Issues still with upgrading though as using package.subpackage for package
# name does not correctly create directory structure
import sys
import os

def recursive_replace(base_path, toreplace, replacement):
    '''Recursive find and replace

    Ignore directories starting with '.' (e.g. .svn)
    '''
    for root, dirs, files in os.walk(base_path):
        # remove directories starting with '.'
        for dir in dirs:
            if dir.startswith('.'):
                dirs.remove(dir)
        for name in files:
            fp = os.path.join(root, name)
            print 'Processing: ', fp
            indata = file(fp).read()
            outdata = indata.replace(toreplace, replacement)
            fo = file(fp, 'w')
            fo.write(outdata)
            fo.close()

def run(cmd):
    print 'Running: ', cmd
    os.system(cmd)

def cleanup_new_install(name):
    opn = name
    rmcmd = 'rm -Rf %s'
    run(rmcmd % 'test.ini')
    run(rmcmd % opn + '.egg_info')
    run('mv %s %s' % ('README.txt', 'README_pylons.txt'))
    run(rmcmd % opn + '/docs')
    run(rmcmd % opn + '/public/index.html')
    run(rmcmd % opn + '/tests/functional')
    run(rmcmd % opn + '/tests/test_models.py')
    run(rmcmd % opn + '/templates/autohandler')

def convert(old_package_name, new_package_name):
    cleanup_new_install(old_package_name)
    # do find and replace on package 
    base_path = os.path.join(os.getcwd(), old_package_name)
    recursive_replace(base_path, old_package_name, new_package_name)

def upgrade(project, pkgname, pkgpath):
    '''
    Run this from the base directory -- i.e. where you have setup.py and README.txt

    pkgpath should be pretty unique (it will be if bothering to use this ...)

    >>> pkgname = 'mypkg.jones'
    >>> pkgpath = 'src/mypkg/jones'
    >>> project = 'blah'
    >>> upgrade(project, pkgname, pkgpath)
    Running:  paster create -t pylons . project=blah package=src/mypkg/jones egg=blah template_engine=genshi
    ...
    >>> info = file('src/mypkg/jones/lib/base.py').read()
    >>> assert pkgname in info

    TODO: other upgrade stuff:
        render_response -> render
        Response(x) -> return x
        response.headers['Content-type'] = 'text/plain'
    '''
    cmd = 'paster create -t pylons . project=%s package=%s egg=%s template_engine=%s' % (
            project, pkgpath, project, 'genshi'
            )
    # run(cmd)
    # TODO: make this more specific (e.g. to ignore MANIFEST.in)
    recursive_replace('.', pkgpath, pkgname)

def _test():
    go_on = raw_input('Warning this will create files in the current directory. Continue (y/n)? ')
    if go_on == 'y':
        import doctest
        doctest.testmod(optionflags=doctest.ELLIPSIS)

if __name__ == '__main__':
    import optparse
    usage = \
'''usage: %prog [options] <action>

convert: convert <old-package-name> <new-package-name>
upgrade: upgrade <project> <pkgname> <pkgpath>
test: run tests
'''
    parser = optparse.OptionParser(usage)
    options, args = parser.parse_args()
    if len(args) == 0:
        parser.print_help()
        sys.exit(1)
    if args[0] == 'convert':
        if len(args) != 2:
            parser.print_help()
            sys.exit(1)
        convert(args[0], args[1])
    elif args[0] == 'upgrade':
        upgrade(args[1], args[2], args[3])
    elif args[0] == 'test':
        _test()
    else:
        parser.print_help()
        sys.exit(1)

