tab -> spaces
[mass-build.git] / vcs.py
diff --git a/vcs.py b/vcs.py
index 8d8d836284a95360222bb16b786777af7d6bc9f3..9f53fe257ab586bca5ca5a96eed226057c4f848f 100644 (file)
--- a/vcs.py
+++ b/vcs.py
 import os, subprocess, re
 
 '''A VCS must have an "update" method with an optional "mode" parameter taking one of the three values below,
 import os, subprocess, re
 
 '''A VCS must have an "update" method with an optional "mode" parameter taking one of the three values below,
-   a "version" method returning a version name (or None),
-   and a "newVersions" method which checks for new versions and prints the result to standard output.'''
+a "version" method returning a version name (or None),
+and a "newVersions" method which checks for new versions and prints the result to standard output.'''
 MODE_FETCH = 0
 MODE_REBASE = 1
 MODE_RESET = 2
 
 def natural_sort_key(val):
 MODE_FETCH = 0
 MODE_REBASE = 1
 MODE_RESET = 2
 
 def natural_sort_key(val):
-       return [ (int(c) if c.isdigit() else c) for c in re.split('([0-9]+)', val) ]
+    return [ (int(c) if c.isdigit() else c) for c in re.split('([0-9]+)', val) ]
 
 def get_non_digit_prefix(val):
 
 def get_non_digit_prefix(val):
-       return re.match('[^0-9]*', val).group(0)
+    return re.match('[^0-9]*', val).group(0)
 
 class GitCommand:
 
 class GitCommand:
-       def __getattr__(self, name):
-               def call(*args):
-                       cmd = ["git", name.replace('_', '-')] + list(args)
-                       p = subprocess.Popen(cmd, stdout=subprocess.PIPE) # TODO use with
-                       (stdout, stderr) = p.communicate()
-                       if p.returncode != 0:
-                               raise Exception("Running %s returned non-zero exit code %d" % (str(cmd), p.returncode))
-                       return filter(len, stdout.split('\n')) # return list of non-empty lines
-               return call
+    def __getattr__(self, name):
+        def call(*args, get_stderr = False):
+            cmd = ["git", name.replace('_', '-')] + list(args)
+            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT if get_stderr else None)
+            return output.decode('utf-8').strip('\n')
+        return call
 git = GitCommand()
 
 # Fetch updates from git
 class Git:
 git = GitCommand()
 
 # Fetch updates from git
 class Git:
-       def __init__(self, folder, config):
-               self.folder = os.path.abspath(folder)
-               self.url = config['url']
-               self.commit = config['version']
+    def __init__(self, folder, config):
+        self.folder = os.path.abspath(folder)
+        self.url = config['url']
+        self.commit = config['version']
 
 
-       def update(self, mode = MODE_REBASE):
-               isBranch = (self.commit.startswith('origin/'))
-               if isBranch:
-                       branchname = self.commit[len('origin/'):]
-               else:
-                       branchname = "tag"
-               # get us a git repository, and the "origin" remote
-               if os.path.exists(self.folder):
-                       # load existing repo
-                       os.chdir(self.folder)
-                       git.remote("set-url", "origin", self.url) # make sure we use the current URL
-               else:
-                       # create a new one
-                       os.makedirs(self.folder)
-                       os.chdir(self.folder)
-                       git.init()
-                       git.remote("add", "origin", self.url)
-               git.fetch("origin")
-               if mode == MODE_FETCH:
-                       return
-               # create/find correct branch
-               if not git.branch("--list", branchname): # the branch does not yet exit
-                       git.branch(branchname, self.commit)
-                       if isBranch: # make sure we track remote branch
-                               git.branch("-u", self.commit, branchname)
-               # update it to the latest remote commit
-               git.checkout(branchname)
-               if mode == MODE_RESET:
-                       git.reset("--hard", self.commit)
-               else:
-                       git.rebase(self.commit)
-               # update submodules
-               git.submodule("update", "--init", "--recursive", "--rebase")
-               # done
-               print "...done",
-               if git.rev_parse("HEAD")[0] != git.rev_parse(self.commit)[0]:
-                       print "(keeping local patches around)",
-               print
+    def update(self, mode = MODE_REBASE):
+        isBranch = (self.commit.startswith('origin/'))
+        if isBranch:
+            branchname = self.commit[len('origin/'):]
+        else:
+            branchname = "tag"
+        # get us a git repository, and the "origin" remote
+        if os.path.exists(self.folder):
+            # load existing repo
+            os.chdir(self.folder)
+            git.remote("set-url", "origin", self.url) # make sure we use the current URL
+        else:
+            # create a new one
+            os.makedirs(self.folder)
+            os.chdir(self.folder)
+            git.init()
+            git.remote("add", "origin", self.url)
+        git.fetch("origin")
+        if mode == MODE_FETCH:
+            return
+        # create/find correct branch
+        if not git.branch("--list", branchname): # the branch does not yet exit
+            git.branch(branchname, self.commit)
+            if isBranch: # make sure we track the correct remote branch
+                git.branch("-u", self.commit, branchname)
+        # update it to the latest remote commit
+        git.checkout(branchname, get_stderr=True)
+        if mode == MODE_RESET:
+            git.reset("--hard", self.commit)
+        else:
+            git.rebase(self.commit)
+        # update submodules
+        git.submodule("update", "--init", "--recursive", "--rebase")
+        # done
+        print("...done", end=' ')
+        if git.rev_parse("HEAD") != git.rev_parse(self.commit):
+            print("(keeping local patches around)", end=' ')
+        print()
 
 
-       def version(self):
-               repo = git.Repo(self.folder)
-               v = repo.git.describe()
-               return v[len(get_non_digit_prefix(v)):] # remove the non-digit prefix from v (so that it starts with a number)
+    def version(self):
+        v = git.describe()
+        return v[len(get_non_digit_prefix(v)):] # remove the non-digit prefix from v (so that it starts with a number)
 
 
-       def checkVersions(self):
-               self.update(mode = MODE_FETCH)
-               currentVersion = git.describe()[0]
-               # get sorted list of tag names with the same non-digit prefix and higher version number
-               tags = git.tag()
-               tags = filter(lambda t: get_non_digit_prefix(t) == get_non_digit_prefix(currentVersion) and natural_sort_key(t) > natural_sort_key(currentVersion), tags)
-               if not tags: return
-               tags.sort(key = natural_sort_key)
-               print "Versions newer than "+currentVersion+" available:"
-               print tags
+    def checkVersions(self):
+        self.update(mode = MODE_FETCH)
+        currentVersion = git.describe()
+        # get sorted list of tag names with the same non-digit prefix and higher version number
+        tags = git.tag().split('\n')
+        tags = [t for t in tags if get_non_digit_prefix(t) == get_non_digit_prefix(currentVersion) and natural_sort_key(t) > natural_sort_key(currentVersion)]
+        if not tags: return
+        tags.sort(key = natural_sort_key)
+        print("Versions newer than "+currentVersion+" available:")
+        print(tags)
 
 # Fetch updates via SVN
 class SVN:
 
 # Fetch updates via SVN
 class SVN:
-       def __init__(self, folder, url):
-               self.folder = os.path.abspath(folder)
-               self.url = url
+    def __init__(self, folder, url):
+        self.folder = os.path.abspath(folder)
+        self.url = url
 
 
-       def update(self, mode = MODE_REBASE):
-               if mode == MODE_FETCH: raise Exception("Just fetching is not supported with SVN")
-               if os.path.exists(self.folder):
-                       os.chdir(self.folder) # go into repository
-                       if mode == MODE_RESET: subprocess.check_call(['svn', 'revert', '-R', '.'])
-                       subprocess.check_call(['svn', 'switch', self.url]) # and update to the URL we got
-               else:
-                       os.makedirs(self.folder) # if even the parent folder does not exist, svn fails
-                       subprocess.check_call(['svn', 'co', self.url, self.folder]) # just download it
-       
-       def version(self):
-               return None
-       
-       def checkVersions(self):
-               print "Version checking not supporting with SVN"
+    def update(self, mode = MODE_REBASE):
+        if mode == MODE_FETCH: raise Exception("Just fetching is not supported with SVN")
+        if os.path.exists(self.folder):
+            os.chdir(self.folder) # go into repository
+            if mode == MODE_RESET: subprocess.check_call(['svn', 'revert', '-R', '.'])
+            subprocess.check_call(['svn', 'switch', self.url]) # and update to the URL we got
+        else:
+            os.makedirs(self.folder) # if even the parent folder does not exist, svn fails
+            subprocess.check_call(['svn', 'co', self.url, self.folder]) # just download it
+    
+    def version(self):
+        return None
+    
+    def checkVersions(self):
+        print("Version checking not supporting with SVN")