Commits

Troy Williams  committed 25fc5f4

Modified hg_utilities.py so that it uses the new repository class

Added the HgHelper.py to contain the repository class.

  • Participants
  • Parent commits 31efd53

Comments (0)

Files changed (2)

+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+"""
+
+Copyright (c) 2011 Troy Williams
+
+License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+"""
+
+import os
+from SubprocessHelper import SubprocessHelper
+
+#Constants
+__uuid__ = '6e4ae415-6afc-409f-97ca-5a7f2a69b655'
+__author__ = 'Troy Williams'
+__email__ = 'troy.williams@bluebill.net'
+__copyright__ = 'Copyright (c) 2011, Troy Williams'
+
+
+
+class Repository():
+
+    def __init__(self, path):
+        self.path = path
+        self.name = os.path.basename(path)
+        self.parent_path = os.path.dirname(path)
+        self.parent_path_name = os.path.basename(self.parent_path)
+        self.relative_name = os.path.join(self.parent_path_name, self.name)
+        self.commands = {'update':['hg', 'update']}
+        self.commands['push'] = ['hg', 'push']
+        self.commands['pull'] = ['hg', 'pull']
+        self.commands['status'] = ['hg', 'status']
+        self.commands['incoming'] = ['hg', 'incoming']
+        self.commands['outgoing'] = ['hg', 'outgoing']
+        self.command_result = ()
+
+    def run_repo_command(self, command):
+        """
+        Execute a command against the repository
+        """
+        if command:
+            subprocess_helper = SubprocessHelper()
+            subprocess_helper.run(command,
+                                  shell=False,
+                                  working_directory=self.path)
+
+            self.standard_output_stream = subprocess_helper.standard_output_stream
+            self.standard_error_stream = subprocess_helper.standard_error_stream
+
+    def update(self):
+        """
+        Execute the hg update command on the repository
+        """
+
+        self.run_repo_command(self.commands['update'])
+
+    def push(self):
+        """
+        Execute the hg push command on the repository
+        """
+
+        self.run_repo_command(self.commands['push'])
+
+    def pull(self):
+        """
+        Executes the hg pull command on the repository
+        """
+
+        self.run_repo_command(self.commands['pull'])
+
+    def incoming(self):
+        """
+        Executes the hg incoming command on the repository
+        """
+
+        self.run_repo_command(self.commands['incoming'])
+
+    def outgoing(self):
+        """
+        Executes the hg outgoing command on the repository
+        """
+
+        self.run_repo_command(self.commands['outgoing'])
+
+    def status(self):
+        """
+        Executes the hg status command on the repository
+        """
+
+        self.run_repo_command(self.commands['status'])
+
+    def has_pending_commits(self):
+        """
+        Determines if the repository has any pending commits. Basically, it
+        executes the status command and examines the result of the standard
+        output stream. If there is anything there then there is a pending commit.
+
+        To see what the outstanding commits are, examine the standard output
+        stream after issuing this command
+        """
+
+        self.status()
+        if self.standard_output_stream:
+            return True
+        else:
+            return False
+
+    def supports_incoming(self):
+        """
+        Interprests the hg incoming message and determines if the repository is
+        setup to receive incoming changesets from the remote repository.
+
+        $ hg incoming
+        abort: repository default not found!
+        """
+
+        self.incoming()
+        m = 'abort: repository default not found!'
+        return not m in self.standard_output_stream[0]
+
+#    def has_incoming_changes(self):
+#        """
+#        ['comparing with https://troy_williams:***@bitbucket.org/troy_williams/source_code',
+#        'searching for changes',
+#        'no changes found',
+#        '']
+#        """
+#
+#        self.incoming()
+#        m = 'no changes found'
+#        return not m in self.standard_output_stream[2]
+
+    def supports_outgoing(self):
+        """
+        Interprets the hg outgoing command and determines if the repository is
+        setup to push changes to a remote repository.
+
+        $ hg outgoing
+        comparing with default-push
+        abort: repository default-push not found!
+        """
+
+        self.outgoing()
+        m = 'abort: repository default not found!'
+        return not m in self.standard_output_stream[1]
+
+def find_repositories(path):
+    """
+    Takes a path and searches it for mecurial repositories. It returns a list of
+    repository objects.
+    """
+
+    path_to_search = path
+    repository_folder_indicator = '.hg'
+    repositories = []
+
+    for current_path, dirs, files in os.walk(path_to_search):
+        if repository_folder_indicator in dirs:
+            repositories.append(Repository(current_path))
+            dirs[:] = []
+
+    return repositories

File hg_utilities.py

 
 import sys
 import os
+import HgHelper
+
 
 __uuid__ = 'ca635163-d33d-4e18-a8d0-53039bea6f18'
-__version__ = '0.4'
 __author__ = 'Troy Williams'
 __email__ = 'troy.williams@bluebill.net'
 __copyright__ = 'Copyright (c) 2011, Troy Williams'
-__date__ = '2011-10-22'
+__version__ = '0.5'
 
-def find_repositories(root):
-    """
-    Search for mecurial repositories and returns the paths that are found.
 
-    It will not continue to search a path once it is determined that a path is a
-    repository.
-    """
+#def find_repositories(root):
+#    """
+#    Search for mecurial repositories and returns the paths that are found.
 
-    path_to_search = root
-    repository_folder_indicator = '.hg'
-    hg_repositories = []
-    for current_path, dirs, files in os.walk(path_to_search):
-        if repository_folder_indicator in dirs:
-            print 'Found repository: %s' % os.path.relpath(current_path,root)
-            hg_repositories.append(current_path)
-            dirs[:] = [] #clear the list of directorys so we stop searching this branch
+#    It will not continue to search a path once it is determined that a path is a
+#    repository.
+#    """
 
-    return hg_repositories
+#    path_to_search = root
+#    repository_folder_indicator = '.hg'
+#    hg_repositories = []
+#    for current_path, dirs, files in os.walk(path_to_search):
+#        if repository_folder_indicator in dirs:
+#            print 'Found repository: %s' % os.path.relpath(current_path,root)
+#            hg_repositories.append(current_path)
+#            dirs[:] = [] #clear the list of directorys so we stop searching this branch
+
+#    return hg_repositories
 
 
 def process_command_line():
 
     return options, args
 
-def run_command(command, working_directory, useshell=False):
+#def run_command(command, working_directory, useshell=False):
+#    """
+#    Takes the list and attempts to run it in the command shell and waits for it
+#    to execute. It then returns the results to the caller.
+#    """
+
+#    subprocess_helper = SubprocessHelper()
+#    subprocess_helper.run(command, shell=useshell, working_directory=working_directory)
+#    return subprocess_helper.standard_output_stream, subprocess_helper.standard_error_stream
+
+
+#def hg_update(hg_repository):
+#    """
+#    Execute the hg update command on the repository
+#    """
+#    cmd = ['hg', 'update']
+#    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+
+
+#def hg_push(hg_repository):
+#    """
+#    Execute the hg push command on the repository
+#    """
+#    cmd = ['hg', 'push']
+#    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+
+
+#def hg_pull(hg_repository):
+#    """
+#    Issues the hg pull command on the specified repository
+#    """
+#    cmd = ['hg', 'pull']
+#    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+
+
+#def hg_status(hg_repository):
+#    """
+#    Issues the hg status command on the specified repository. If anything is
+#    returned then the repository has a pending commit and should not have any
+#    push or pull operations performed on it.
+#    """
+#    cmd = ['hg', 'status']
+#    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+
+
+#def hg_incomming(hg_repository):
+#    """
+#    issues an hg incoming command on the repository
+
+#    $ hg incoming
+#    comparing with /home/troy/tmp/repos/repo1
+#    searching for changes
+#    no changes found
+
+#    $ hg incoming
+#    abort: repository default not found!
+
+
+#    $ hg incoming
+#    comparing with /home/troy/tmp/repos/repo1
+#    searching for changes
+#    changeset:   1:f4e4c8ffd56b
+#    tag:         tip
+#    user:        Troy Williams <troy.williams@bluebill.net>
+#    date:        Sat Oct 22 14:52:31 2011 -0400
+#    summary:     added a file
+#    """
+
+#    cmd = ['hg', 'incoming']
+#    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+
+#def find_pending_commits(repositories):
+#    """
+#    Searches each repository for pending commits. If any are found the repository
+#    is added to a new list and returned
+#    """
+
+#    pending_commits = []
+#    for repo in repositories:
+#        output, error = hg_status(repo)
+#        if output:
+#            pending_commits.append(repo)
+
+#    return pending_commits
+
+#def is_remote_incoming_repo_setup(hg_incoming_message):
+#    """
+#    interprets the hg incomming message and determines if the repo has a remote
+#    repository setup
+
+#    hg_incoming_message is a tuple of (std.output, std.error). Check to see
+#    if there is the abort message
+#    """
+
+#    m = 'abort: repository default not found!'
+#    return m in hg_incoming_message[1]
+
+
+#def update_repositories(repositories):
+#    """
+#    Takes the list of repositories and updates them
+#    """
+#    for repo in repositories:
+#        print 'updating', repo
+#        output, error = hg_update(repo)
+#        if error:
+#            print error
+#            continue
+
+#        print output
+
+#def pull_repository_changes(repositories):
+#    """
+#    Takes the list of repositories and pulls the changes
+#    """
+#    for repo in repositories:
+#        print 'Pulling changes for', repo
+#        output, error = hg_pull(repo)
+#        if error:
+#            print error
+#            continue
+
+#def find_repos_with_default_incoming_sync(repositories):
+#    """
+#    Takes a list of repositories and finds the ones that are configured to pull
+#    remote changes.
+#    """
+#    repos_with_sync_capabilities = []
+#    for repo in repositories:
+#        status = hg_incomming(repo) #status is a tuple (std, stderr)
+#        if is_remote_incoming_repo_setup(status):
+#            print repo, 'is not configured for synchronization'
+#        else:
+#            repos_with_sync_capabilities.append(repo)
+
+#    return repos_with_sync_capabilities
+
+#def pull_changes_and_update(repositories):
+#    """
+#    Takes the repositories and pulls remote changes and then updates them
+#    """
+
+#    repos_with_sync_capabilities = find_repos_with_default_incoming_sync(repositories)
+#    pull_repository_changes(repos_with_sync_capabilities)
+#    update_repositories(repos_with_sync_capabilities)
+
+#def push_repository_changes(repositories):
+#    """
+#    Takes the list of repositories and pushes the changes
+#    """
+#    for repo in repositories:
+#        print 'Pushing changes for', repo
+#        output, error = hg_push(repo)
+#        if error:
+#            print error
+#            continue
+
+def print_repositories(repositories, path):
     """
-    Takes the list and attempts to run it in the command shell and waits for it
-    to execute. It then returns the results to the caller.
-    """
-    if not command:
-        raise Exception, 'Valid command required - fill the list please!'
-
-    import subprocess
-    p = subprocess.Popen(command,
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE,
-                         shell=useshell,
-                         cwd=working_directory)
-
-    output_stream, error_stream = p.communicate()
-    return output_stream, error_stream
-
-
-def hg_update(hg_repository):
-    """
-    Execute the hg update command on the repository
-    """
-    cmd = ['hg', 'update']
-    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
-
-
-def hg_push(hg_repository):
-    """
-    Execute the hg push command on the repository
-    """
-    cmd = ['hg', 'push']
-    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
-
-
-def hg_pull(hg_repository):
-    """
-    Issues the hg pull command on the specified repository
-    """
-    cmd = ['hg', 'pull']
-    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
-
-
-def hg_status(hg_repository):
-    """
-    Issues the hg status command on the specified repository. If anything is
-    returned then the repository has a pending commit and should not have any
-    push or pull operations performed on it.
-    """
-    cmd = ['hg', 'status']
-    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
-
-
-def hg_incomming(hg_repository):
-    """
-    issues an hg incoming command on the repository
-
-    $ hg incoming
-    comparing with /home/troy/tmp/repos/repo1
-    searching for changes
-    no changes found
-
-    $ hg incoming
-    abort: repository default not found!
-
-
-    $ hg incoming
-    comparing with /home/troy/tmp/repos/repo1
-    searching for changes
-    changeset:   1:f4e4c8ffd56b
-    tag:         tip
-    user:        Troy Williams <troy.williams@bluebill.net>
-    date:        Sat Oct 22 14:52:31 2011 -0400
-    summary:     added a file
+    Takes a list of repositores and a common path and displays the name
+    of each repository.
     """
 
-    cmd = ['hg', 'incoming']
-    return run_command(cmd, hg_repository) #tuple of (std.output, std.error)
+    for repo in repositories:
+        print '%s' % os.path.relpath(repo.path, path)
 
 def find_pending_commits(repositories):
     """
 
     pending_commits = []
     for repo in repositories:
-        output, error = hg_status(repo)
-        if output:
+        if repo.has_pending_commits():
             pending_commits.append(repo)
 
     return pending_commits
 
-def is_remote_incoming_repo_setup(hg_incoming_message):
+def pull_repository_changes(repositories):
     """
-    interprets the hg incomming message and determines if the repo has a remote
-    repository setup
+    Pulls the changes for the repositories in the list
+    """
+    for repo in repositories:
+        print 'Pulling changes for %s' % repo.name
+        repo.pull()
+        if repo.standard_error_stream:
+            print repo.standard_error_stream
+            continue
 
-    hg_incoming_message is a tuple of (std.output, std.error). Check to see
-    if there is the abort message
+            print repo.standard_output_stream
+
+def push_repository_changes(repositories):
     """
+    Pushes the repository changes
+    """
+    for repo in repositories:
+        print 'Pushing changes for %s' % repo.name
+        repo.push()
+        if repo.standard_error_stream:
+            print repo.standard_error_stream
+            continue
 
-    m = 'abort: repository default not found!'
-    return m in hg_incoming_message[1]
-
+            print repo.standard_output_stream
 
 def update_repositories(repositories):
     """
-    Takes the list of repositories and updates them
+    Updates the repositories
     """
     for repo in repositories:
-        print 'updating', repo
-        output, error = hg_update(repo)
-        if error:
-            print error
+        print 'Updating %s' % repo.name
+        repo.update()
+        if repo.standard_error_stream:
+            print repo.standard_error_stream
             continue
 
-        print output
-
-def pull_repository_changes(repositories):
-    """
-    Takes the list of repositories and pulls the changes
-    """
-    for repo in repositories:
-        print 'Pulling changes for', repo
-        output, error = hg_pull(repo)
-        if error:
-            print error
-            continue
-
-def find_repos_with_default_incoming_sync(repositories):
-    """
-    Takes a list of repositories and finds the ones that are configured to pull
-    remote changes.
-    """
-    repos_with_sync_capabilities = []
-    for repo in repositories:
-        status = hg_incomming(repo) #status is a tuple (std, stderr)
-        if is_remote_incoming_repo_setup(status):
-            print repo, 'is not configured for synchronization'
-        else:
-            repos_with_sync_capabilities.append(repo)
-
-    return repos_with_sync_capabilities
+            print repo.standard_output_stream
 
 def pull_changes_and_update(repositories):
     """
     Takes the repositories and pulls remote changes and then updates them
     """
 
-    repos_with_sync_capabilities = find_repos_with_default_incoming_sync(repositories)
-    pull_repository_changes(repos_with_sync_capabilities)
-    update_repositories(repos_with_sync_capabilities)
+    for repo in repositories:
 
-def push_repository_changes(repositories):
-    """
-    Takes the list of repositories and pushes the changes
-    """
-    for repo in repositories:
-        print 'Pushing changes for', repo
-        output, error = hg_push(repo)
-        if error:
-            print error
-            continue
+        if repo.supports_incoming():
+            print 'Pulling and updating changes for %s' % repo.relative_name
+            repo.pull()
+            if repo.standard_error_stream:
+                print repo.standard_error_stream
+                continue
+
+            repo.update()
+            if repo.standard_error_stream:
+                print repo.standard_error_stream
+                continue
+
+            print ' '.join(repo.standard_output_stream)
 
 def main():
     """
 
     repositories = []
     for path in search_paths:
-        print 'Searching for repositories in %s...' % path
-        hg_repositories = find_repositories(path)
-        repositories.extend(hg_repositories)
+        print 'Searching %s...' % path
+        found_repositories = HgHelper.find_repositories(path)
+        if found_repositories:
+            print 'Found Repositories:'
+            print_repositories(found_repositories, path)
+            repositories.extend(found_repositories)
 
-    if len(repositories) == 0:
-        print 'No repositories found...'
-        return 0
-
-    #If any of the repos have pending commits - ignore them and warn the user
     pending_commits = find_pending_commits(repositories)
     if pending_commits:
         repositories = [p for p in repositories if p not in pending_commits]
         for repo in pending_commits:
-            print repo, 'has pending commits. Please commit the changes!'
+            print repo.relative_name, 'has pending commits.'
+            print '\n'.join(repo.standard_output_stream)
 
     if len(repositories) == 0:
-        print 'No repositories left to process...'
-        return 0
+        return -1
 
 #At this point we have a list of repositories that do not have pending commits
     if options.pullupdate: