Source

hgsync / hgcmd.py

Full commit
import os
import logging, logging.config
from datetime import datetime
from functools import wraps
from mercurial import cmdutil, ui, commands, patch, hg

logging.config.fileConfig('logconfig.ini')
log = logging.getLogger('SyncLog')
    
def auto_branch_name(dest):
    "generates branch name based on datetime.now()"
    for piece in dest.split(os.path.sep):
        if piece != '': break
    now = datetime.now()
    d, t = now.date(), now.time()
    dstr = '/'.join([str(d.year)[2:],
                    str(d.month).zfill(2),
                    str(d.day).zfill(2)])
    tstr = ':'.join([str(t.hour).zfill(2),
                    str(t.minute).zfill(2),
                    str(t.second).zfill(2)])
    return '-'.join([dstr, tstr, piece])

def init(dest):
    "hg init dest"
    return commands.init(ui.ui(), dest=dest)

def diff(dest, u=ui.ui()):
    "prints diff log"
    repo = hg.repository(ui, dest)
    m = cmdutil.match(repo)
    node1, node2 = cmdutil.revpair(repo, 0)
    it = patch.diff(repo, node1, node2, match=m)
    if len(list(it)) > 0:
        for line in it:
            log.debug(line) # TODO: output to mail log
        return 1
    else: return 0

def commit(dest, comment, u=ui.ui()):
    "hg commit"
    log.info("commiting for %s" % dest)
    log.info("Message: %s" % comment)
    repo = hg.repository(u, dest)
    return commands.commit(u, repo, message=comment, addremove=True)

def push(src, dest, u=ui.ui()):
    "hg push -f"
    src_repo = hg.repository(u, src)
    dest_repo = hg.repository(u, dest)
    return src_repo.push(dest_repo, force=True)

def update_branch(dest, br_name=None, u=ui.ui()):
    "hg update br_name"
    repo = hg.repository(u, dest)
    return commands.update(u, repo, node=br_name)

def branch(dest, br_name, u=ui.ui()):
    "hg branch br_name"
    repo = hg.repository(u, dest)
    return commands.branch(u, repo, label=br_name)

def autobranch(dest, u=ui.ui()):
    "Create new branch if repo is changed"
    if repo_is_changed(dest, u):
        br_name = auto_branch_name(dest)
        print "branch to %s, name %s" % (dest, br_name)
        branch(dest, br_name, u=u)
        commit(dest, 'auto commit', u)
        update_branch(dest, br_name='default', u=u)
        return True
    else:
        update_branch(dest, br_name='default', u=u)
        return False

def repo_is_changed(dest, u=ui.ui()):
    "'hg status' stripped down. Return true if the repo is changed."
    repo = hg.repository(u, dest)
    node1, node2 = cmdutil.revpair(repo, 0)
    m = cmdutil.match(repo)
    stat = repo.status(node1, node2, m, False, False, True)
    return len(filter(lambda x: len(x)!=0, stat)) != 0

def autosync(project_dir, syncgroup, u=ui.ui()):
    "Magic"
    for syncdir in syncgroup:
        lockflag = os.path.join(syncdir, 'LOCKED.FLG')
        if os.path.exists(lockflag):
            log.info("Skipping locked %s" % syncdir)
            continue
        log.info("Synchronizing %s" % syncdir)
        push(project_dir, syncdir, u)
        branched = autobranch(syncdir, u)
        if branched:
            log.info("Auto branch created on %s" % syncdir)
            log.info("Synchronizing back..")
            autosync(syncdir, syncgroup, u)
            break