changeset 6:ef895ddba2d3

add an apply command
author Jeff Hammel <jhammel@mozilla.com>
date Wed, 21 Jul 2010 16:18:59 -0700
parents 0bfbd062765d
children 67ec22ce347c
files gut/command.py gut/main.py
diffstat 2 files changed, 73 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/gut/command.py	Wed Jul 21 13:49:46 2010 -0700
+++ b/gut/command.py	Wed Jul 21 16:18:59 2010 -0700
@@ -183,6 +183,12 @@
                 elif value is False:
                     parser.add_option('--%s' % key, action='store_true',
                                       default=False, help=help)
+                elif type(value) in set([type(()), type([])]):
+                    if value:
+                        help += ' [DEFAULT: %s]' % value
+                    parser.add_option('--%s' % key, action='append',
+                                      default=list(value),
+                                      help=help)
                 else:
                     if value is not None:
                         help += ' [DEFAULT: %s]' % value
--- a/gut/main.py	Wed Jul 21 13:49:46 2010 -0700
+++ b/gut/main.py	Wed Jul 21 16:18:59 2010 -0700
@@ -42,22 +42,33 @@
     a workflow for git
     """
 
-    def __init__(self, remote=None, simulate=False):
+    def __init__(self, remote=None, simulate=False, branches=('master',)):
         """
         - remote: name of the remote repository in .git/config
         - simulate: print what calls will be used but don't run them
+        - branches: branches to apply to
         """
+
+        # sanity check
+        self.root()
+
         self.remote = remote
         self.simulate = simulate
+        self.branches = branches
         if simulate:
             globals()['call'] = fake_call
 
+
     def update(self):
-        """update the master and the branch you're on"""
+        """update the master"""
+        branch = self.branch()
+        if self.simulate:
+            branch = '<branch>'
         call(['git', 'checkout', 'master'])
         call(['git', 'pull', 'origin', 'master'])
         if self.remote:
             call(['git', 'pull', self.remote, 'master'])
+        call(['git', 'checkout', branch])
 
     def feature(self, name):
         """make a new feature branch"""
@@ -65,8 +76,13 @@
         call(['git', 'checkout', '-b', name])
         call(['git', 'push', 'origin', name])
 
-    def patch(self, output=None):
-        """generate a patch for review"""
+    def patch(self, output=None, logfile=None):
+        """
+        generate a patch for review
+        - output: name of patch
+        - logfile: name of file to output the log to [DEFAULT: stdout]
+        """
+        self.update()
         diff = call(['git', 'diff', 'master'], pipe=True, output=False)
         log = call(['git', 'log', 'master..'], pipe=True, output=False)
         if self.simulate:
@@ -107,17 +123,62 @@
         f = file(output, 'w') # write the output to a patch file
         print >> f, diff
         f.close()
-        return log
+
+        # output the log
+        if logfile:
+            f = file(logfile, 'w') # write the log to a file
+            print >> f, log
+        else:
+            return log
+
+    def apply(self):
+        """
+        apply the existing feature branch to master as a patch
+        """
+
+        # sanity check
+        branch = self.branch()
+        assert branch != 'master', "Can't apply master to itself!"
+        assert self.branches, "No branches defined!"
+
+        # get the patch
+        self.patch(branch + '.diff', branch + '.log')
+        diff = os.path.abspath(branch + '.diff')
+        log = os.path.abspath(branch + '.log')
+
+        # apply the patch
+        cwd = os.getcwd()
+        os.chdir(self.root())
+        for b in self.branches:
+            call(['git', 'checkout', b])
+            call(['patch -p1 < %s' % diff])
+            call(['git', 'commit', '-a', '-F', log])
+            call(['git', 'push', 'origin', b])
+            if self.remote:
+                call(['git', 'push', self.remote, b])
+
+        # cleanup
+        call(['git', 'checkout', branch])
+        os.chdir(cwd)
 
     def branch(self):
         """print what branch you're on"""
         output = call(['git', 'branch'], output=False, pipe=True)
         if self.simulate:
-            return
+            return 
         for line in output['stdout'].splitlines():
             if line.startswith('*'):
                 return line[1:].strip()
 
+    def root(self):
+        """return (relative) root location of repository"""
+        
+        output = call(['git', 'rev-parse', '--show-cdup'], output=False, pipe=True)
+        location = output['stdout'].strip()
+        if not location:
+            return '.'
+        return location
+
 def main(args=sys.argv[1:]):
     parser = CommandParser(gut)
     parser.invoke(args)