Morpheus / Mbed OS mbed-Client-Morpheus-hg

Dependencies:   mbed-os

Revision:
3:47aa05d37724
Child:
4:6e987db7a950
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/neo.py	Wed Mar 30 20:17:20 2016 +0000
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import re
+import subprocess
+import os
+import contextlib
+import collections
+
+# Subparser handling
+parser = argparse.ArgumentParser()
+subparsers = parser.add_subparsers()
+
+def subcommand(name, *args, **kwargs):
+    def subcommand(command):
+        subparser = subparsers.add_parser(name, **kwargs)
+    
+        for arg in args:
+            subparser.add_argument(arg)
+    
+        def thunk(parsed_args):
+            ordered_args = [vars(parsed_args)[arg] for arg in args]
+            return command(*ordered_args)
+    
+        subparser.set_defaults(command=thunk)
+        return command
+    return subcommand
+
+# Process execution
+class ProcessException(Exception):
+    pass
+
+def popen(command, stdin=None):
+    # print for debugging
+    print ' '.join(command)
+    proc = subprocess.Popen(command)
+
+    if proc.wait() != 0:
+        raise ProcessException(proc.returncode)
+
+def pquery(command, stdin=None):
+    proc = subprocess.Popen(command, stdout=subprocess.PIPE)
+    stdout, _ = proc.communicate(stdin)
+
+    if proc.returncode != 0:
+        raise ProcessException(proc.returncode)
+
+    return stdout
+
+# Directory navigation
+@contextlib.contextmanager
+def cd(newdir):
+    prevdir = os.getcwd()
+    os.chdir(newdir)
+    try:
+        yield
+    finally:
+        os.chdir(prevdir)
+
+def iterlibs(dir=None):
+    for file in os.listdir(dir or os.getcwd()):
+        if file.startswith('.'):
+            continue
+        elif os.path.isfile(file) and file.endswith('.lib'):
+            with open(file) as f:
+                yield f.read().strip()
+
+def savelib(repo):
+    print repo.name, '->', repo.url
+
+    with open(repo.lib, 'w') as f:
+        f.write(repo.url + '\n')
+
+
+# Handling for multiple version controls
+class Repo(object):
+    def __init__(self, path=None):
+        self.path = path or os.getcwd()
+        self.name = os.path.basename(self.path)
+        self.update()
+
+    @classmethod
+    def fromurl(cls, url):
+        repo = cls.__new__(cls)
+
+        m = re.match('^(.*/([+a-zA-Z0-9_-]+)/?)(?:#(.*))?$', url)
+        repo.repo = m.group(1)
+        repo.name = m.group(2)
+        repo.hash = m.group(3)
+
+        repo.path = os.path.join(os.getcwd(), repo.name)
+        return repo
+
+    @property
+    def lib(self):
+        return self.path + '.lib'
+
+    @property
+    def url(self):
+        if self.repo:
+            if self.hash:
+                return self.repo + '#' + self.hash
+            else:
+                return self.repo
+
+    def update(self):
+        if os.path.isdir(self.path):
+            self.type = self.gettype()
+            self.hash = self.gethash()
+
+        if os.path.isfile(self.lib):
+            with open(self.lib) as f:
+                temp = Repo.fromurl(f.read())
+                self.repo = temp.repo
+
+    def gettype(self):
+        for type, dir in [('git', '.git'), ('hg', '.hg')]:
+            if os.path.isdir(os.path.join(self.path, dir)):
+                return type
+
+    def gethash(self):
+        with cd(self.path):
+            if self.type == 'git':
+                return pquery(['git', 'rev-parse', '--short', 'HEAD']).strip()
+            elif self.type == 'hg':
+                return pquery(['hg', 'id', '-i']).strip()
+
+# Clone command
+@subcommand('import', 'url',
+    help='recursively import a repository')
+def import_(url):
+    repo = Repo.fromurl(url)
+
+    for type in ['git', 'hg']:
+        try:
+            popen([type, 'clone', repo.repo])
+            break
+        except:
+            pass
+
+    repo.type = repo.gettype()
+
+    if repo.hash:
+        with cd(repo.path):
+            popen([repo.type, 'checkout', repo.hash])
+
+    repo.update()
+
+    with cd(repo.path):
+        for lib in iterlibs():
+            import_(lib)
+
+# Install/uninstall command
+@subcommand('install', 'url',
+    help='add a submodule to the current repository')
+def install(url):
+    cwd = Repo()
+    repo = Repo.fromurl(url)
+
+    import_(url)
+
+    repo.update()
+    savelib(repo)
+
+    popen([cwd.type, 'add', repo.lib])
+
+@subcommand('uninstall', 'module',
+    help='remove a submodule')
+def uninstall(module):
+    cwd = Repo()
+    repo = Repo(module)
+
+    popen([cwd.type, 'rm', '-f', repo.lib])
+    if cwd.type == 'hg':
+        popen(['rm', '-f', repo.lib])
+
+    popen(['rm', '-rf', repo.path])
+
+# Synch command
+@subcommand('synch',
+    help='synchronize lib files')
+def synch():
+    cwd = Repo()
+
+    for lib in iterlibs():
+        repo = Repo.fromurl(lib)
+        repo.update()
+        if lib == repo.url:
+            continue
+
+        savelib(repo)
+
+        if cwd.type == 'git':
+            popen([cwd.type, 'add', repo.lib])
+
+# Parse/run command
+args = parser.parse_args()
+status = args.command(args)
+sys.exit(status or 0)
+