#!/usr/bin/python
# Filename:      hg-mirror
# Purpose:       create a full mirror over hgwebdir
# Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
# Bug-Reports:   see http://grml.org/bugs/
# License:       This file is licensed under the GPL v2.
################################################################################

import os
import sys
import optparse
import re

from hgutil.hg.util import walkrepos_web
from hgutil.hg.simple import syncRepos
from hgutil.exception import CmdException
from hgutil.util import DirChanger


def syncRepositories(source, ignore, strip, tryflag=False):
    imatch = re.compile(ignore)
    if strip:
        smatch = re.compile("^" + strip.strip("/") + "/.*")
    error = True
    for path_orig in walkrepos_web(source):
        path = path_orig[len(source):].lstrip("/") + "/"
        if strip:
            if smatch.match(path) == None:
                continue
            path = smatch.sub("", path)
        if imatch.search(path) != None:
            continue
        if path.find('/../') != -1:
            print 'Error: unallowed escaption ../ in path:', path
            continue
        url = source + '/' + path
        repos = path.strip('/')
        tmp = repos.rsplit('/', 1)
        dir = DirChanger()
        if len(tmp) == 2:
            if not tryflag:
                dir.up(tmp[0], create=True)
            repos = tmp[1]
        try:
            def notifier(url):
                print "Info: added", url
            try:
                if tryflag:
                    notifier(repos)
                else:
                    syncRepos(path_orig, repos, notifier)
            except CmdException, e:
                print 'Error: %s: %s' %(repos, str(e))
                error = False
        finally:
            dir.down()
    return error

if __name__ == '__main__':
    parser = optparse.OptionParser(usage="usage: %prog [options] <source>")
    parser.add_option("-i", "--ignore", dest="ignore", default="""(?!)""", metavar="regexp",
            help="Filter list of repository names")
    parser.add_option("-s", "--strip", dest="strip", default=False, metavar="regexp",
            help="Strip prefix from repos path")
    parser.add_option("--try", action="store_true", dest="tryflag", default=False,
            help="Do not sync repositories, only print what would be done")
    (opts, args) = parser.parse_args()
    if len(args) != 1:
        parser.print_help()
        parser.error("Please give a source to sync from")
    source = args[0]
    ret = syncRepositories(source, ignore=opts.ignore, strip=opts.strip, tryflag=opts.tryflag)
    if not ret:
        sys.exit(1)

# vim: foldmethod=marker
