##############################################################################
#
# Copyright (c) 2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""svn to git conversion helper

Based loosely on the svn2git ruby tool
"""

import os
import sys
import xml.etree.ElementTree

def s(command):
    print 'Running command:', command
    if os.system(command):
        raise SystemError

def r(command):
    f = os.popen(command)
    result = f.read()
    f.close()
    return result

def main(args=None):
    if args is None:
        args = sys.argv[1:]

    url, authors = args

    s('git svn init --no-metadata -s %s' % url)
    s('git config svn.authorsfile %s' % authors)
    s('git svn fetch')

    for tag in r('svn ls %s/tags' % url).strip().split():
        if tag[-1] == '/':
            tag = tag[:-1]
        f = os.popen('svn log --xml -l1 %s/tags/%s' % (url, tag))
        date = xml.etree.ElementTree.ElementTree(
            file=f).find('logentry').find('date').text
        f.close()
        s("GIT_COMMITTER_DATE=%r git tag %r 'tags/%s'" % (
            date.replace('T', ' ').replace('Z', ' +0000'),
            tag, tag,
            ))

    for branch in r('svn ls %s/branches' % url).strip().split():
        if branch[-1] == '/':
            branch = branch[:-1]
        s('git checkout %s' % branch)
        s('git checkout -b %s' % branch)

        # Not sure if this is necessary, or sufficient. The Ruby
        # version ran into trouble when git left files around between
        # branche checkouts.  I haven't had the problem, with this
        # script, which unlike the Ruby version, doesn't process
        # deleted branches.
        s('git reset --hard HEAD')

    s('git checkout trunk')
    s('git branch -D master')
    s('git checkout -f -b master')
    s('git branch -d -r trunk')
    s('git gc')

if __name__ == '__main__':
    main()
