Source

hg_utilities / hg_utilities.py

Full commit
#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""

This script will take a series of search paths and recursively search them
for .hg folders. If an .hg folder is found then it is deemed a repository and
added to a list for processing. It then checks to see if there are any pending
commits in the repo and notifies the user of such.

Copyright (c) 2011 Troy Williams

License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
"""

import sys
import os
import HgHelper

__uuid__ = 'ca635163-d33d-4e18-a8d0-53039bea6f18'
__author__ = 'Troy Williams'
__email__ = 'troy.williams@bluebill.net'
__copyright__ = 'Copyright (c) 2011, Troy Williams'
__version__ = '0.6'


def process_command_line():
    """
    From the Docs: http://docs.python.org/library/optparse.html
    """

    from optparse import OptionParser

    usage = "usage: %prog [options] search_path1 search_path2 search_path3..."
    parser = OptionParser(usage=usage, version="%prog v" + __version__)
    parser.add_option("-p", "--pull", action="store_true",
                                      dest="pull",
                                      help="Pull remote changes to local \
                                      repository")
    parser.add_option("", "--pullupdate", action="store_true",
                                          dest="pullupdate",
                                          help="Pull remote changes to local \
                                                repository and update to \
                                                tip.")
    parser.add_option("-u", "--update", action="store_true",
                                         dest="update",
                                         help="Update local repositories to \
                                               tip.")
    parser.add_option("-s", "--push", action="store_true",
                                      dest="push",
                                      help="Push local changes to remote \
                                            repository.")

    options, args = parser.parse_args(args=None, values=None)
    if len(args) == 0:
        parser.error('At least one search path is required!')
        parser.print_help()

    return options, args

def print_repo_error(repo):
    """
    Print the repo standard error stream to the standard output.
    """
    print repo.standard_error_stream

def has_repo_error_occured(repo):
    """
    If an error has occured with the last command issued to the repository, the
    error stream should contain something. This routine will true if an error
    occurred.
    """
    if repo.standard_error_stream:
        return True
    else:
        return False

def pull_update_repo(repo):
    """
    Issues a pull then update command against the repository.
    """

    if not pull_repo(repo):
        return

    update_repo(repo)


def pull_repo(repo):
    """
    Issues a pull command against the repository.
    """

    if repo.supports_incoming():
        print 'Pulling changes for %s' % repo.relative_repo_path
        repo.pull()
        if has_repo_error_occured(repo):
            print_repo_error(repo)
            return False
        return True

    return False

def push_repo(repo):
    """
    Issues a pull command against the repository.
    """

    if repo.supports_outgoing():
        print 'Pushing changes for %s' % repo.relative_repo_path
        repo.push()
        if has_repo_error_occured(repo):
            print_repo_error(repo)
            return False
        return True

    return False


def update_repo(repo):
    """
    Issues an update command against the repository.
    """

    print 'Updating %s' % repo.relative_repo_path
    repo.update()
    if has_repo_error_occured(repo):
        print_repo_error(repo)
        return False

    print ' '.join(repo.standard_output_stream)
    return True


def process_repo_based_on_options(repo, options):
    """
    Determines what to do with the repository based on the user defined options.
    """

    if options.pullupdate:
        pull_update_repo(repo)

    elif options.pull:
        pull_repo(repo)

    elif options.push:
        push_repo(repo)

    elif options.update:
        update_repo(repo)

    else:
        print parser.print_help()


def main():
    """
    Search for the repositories in the given path(s). Process the found repo(s)
    based on the user defined options.
    """

    options, args = process_command_line()

    for arg in args:
        path = os.path.abspath(arg)
        print 'Searching %s...' % path

        for repo_path in HgHelper.find_repositories(path):
            repo = HgHelper.Repository(repo_path)
            repo.relative_repo_path = os.path.relpath(repo.path, path)
            print 'Found: ', repo.relative_repo_path

            if repo.has_pending_commits():
                print repo.relative_repo_path, 'has pending commits:'
                print '\n'.join(repo.standard_output_stream)
                continue

            process_repo_based_on_options(repo, options)
            print ''
    return 0


if __name__ == '__main__':
    status = main()
    sys.exit(status)