Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-os
Diff: neo.py
- Revision:
- 15:a6b1f4e65bf4
- Parent:
- 13:3ae12fe3354a
- Child:
- 16:b54f256e339e
--- a/neo.py Wed Mar 30 02:00:10 2016 -0500 +++ b/neo.py Wed Mar 30 02:05:41 2016 -0500 @@ -1,283 +1,283 @@ -#!/usr/bin/env python - -import argparse -import sys -import re -import subprocess -import os -import contextlib -import collections -import shutil -from itertools import * - -# 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: - if arg.endswith('?'): - subparser.add_argument(arg.strip('?'), nargs='?') - elif arg.endswith('*'): - pass - else: - subparser.add_argument(arg) - - def thunk(parsed_args): - ordered_args = [vars(parsed_args)[arg.strip('?*')] - if not arg.endswith('*') else remainder - 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, **kwargs): - # print for debugging - print ' '.join(command) - proc = subprocess.Popen(command, **kwargs) - - if proc.wait() != 0: - raise ProcessException(proc.returncode) - -def pquery(command, stdin=None, **kwargs): - proc = subprocess.Popen(command, stdout=subprocess.PIPE, **kwargs) - 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 root, dirs, files in os.walk(dir or os.getcwd()): - if os.path.basename(root).startswith('.'): - del dirs[:] - continue - - for file in files: - if file.startswith('.'): - continue - elif file.endswith('.lib'): - with open(os.path.join(root, file)) as f: - yield f.read().strip(), os.path.join(root, file[:-4]) - if file[:-4] in dirs: - dirs.remove(file[:-4]) - -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, name=None): - repo = cls.__new__(cls) - - m = re.match('^(.*/([+a-zA-Z0-9_-]+)/?)(?:#(.*))?$', url) - repo.repo = m.group(1) - repo.name = name or 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 [('hg', '.hg'), ('git', '.git')]: - 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', 'name?', - help='recursively import a repository') -def import_(url, name=None): - repo = Repo.fromurl(url, name) - - for type in ['hg', 'git']: - try: - popen([type, 'clone', repo.repo, repo.path]) - 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 url, lib in iterlibs(): - import_(url, lib) - -# Deploy command -@subcommand('deploy', - help='recursively import libraries in current directory') -def deploy(): - for url, lib in iterlibs(): - import_(url, lib) - -# Install/uninstall command -@subcommand('add', 'url', 'name?', - help='add a library to the current repository') -def add(url, name): - cwd = Repo() - repo = Repo.fromurl(url, name) - - import_(url) - - repo.update() - savelib(repo) - - popen([cwd.type, 'add', repo.lib]) - -@subcommand('remove', 'library', - help='remove a library from the current repository folder') -def remove(library): - cwd = Repo() - repo = Repo(library) - - popen([cwd.type, 'rm', '-f', repo.lib]) - if cwd.type == 'hg': - os.remove(repo.lib) - - shutil.rmtree(repo.path) - -# Publish command -@subcommand('publish', - help='recursively publish changes to remote repositories') -def publish(): - cwd = Repo() - - for url, lib in iterlibs(): - if os.path.isdir(lib): - with cd(lib): - publish() - -# if cwd.type == 'git': -# if pquery(['git' -# -# if (cwd.type == 'git' and pquery(['git', 'diff', '--name-only', 'HEAD'])) - print 'DONT WORK YET' - -# Synch command -@subcommand('synch', - help='synchronize lib files') -def synch(): - cwd = Repo() - - for url, lib in iterlibs(): - repo = Repo.fromurl(url, lib) - repo.update() - if lib == repo.url: - continue - - savelib(repo) - - if cwd.type == 'git': - popen([cwd.type, 'add', repo.lib]) - -# Compile command -@subcommand('compile', 'args*', - help='compile project using workspace_tools') -def compile(args): - cwd = Repo() - - if not os.path.isdir('mbed-os'): - sys.stderr.write('Warning! mbed-os not found?') - sys.exit(-1) - - if not os.path.isfile('mbed_settings.py'): - shutil.copy('mbed-os/tools/settings.py', 'mbed_settings.py') - - if os.path.isfile('MACROS.txt'): - with open('MACROS.txt') as f: - macros = f.read().splitlines() - - env = os.environ.copy() - env['PYTHONPATH'] = '.' - popen(['python', 'mbed-os/tools/make.py'] - + list(chain.from_iterable(izip(repeat('-D'), macros))) - + ['--source=%s' % cwd.path, - '--build=%s' % os.path.join(cwd.path, '.build')] - + args, - env=env) - -# Export command -@subcommand('export', 'args*', - help='generate project files') -def export(args): - cwd = Repo() - - if not os.path.isdir('mbed-os'): - sys.stderr.write('Warning! mbed-os not found?') - sys.exit(-1) - - if not os.path.isfile('mbed_settings.py'): - shutil.copy('mbed-os/tools/settings.py', 'mbed_settings.py') - - popen(['python', 'mbed-os/tools/project.py', - '--source=%s' % cwd.path]) - -# Parse/run command -args, remainder = parser.parse_known_args() -status = args.command(args) -sys.exit(status or 0) - +#!/usr/bin/env python + +import argparse +import sys +import re +import subprocess +import os +import contextlib +import collections +import shutil +from itertools import * + +# 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: + if arg.endswith('?'): + subparser.add_argument(arg.strip('?'), nargs='?') + elif arg.endswith('*'): + pass + else: + subparser.add_argument(arg) + + def thunk(parsed_args): + ordered_args = [vars(parsed_args)[arg.strip('?*')] + if not arg.endswith('*') else remainder + 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, **kwargs): + # print for debugging + print ' '.join(command) + proc = subprocess.Popen(command, **kwargs) + + if proc.wait() != 0: + raise ProcessException(proc.returncode) + +def pquery(command, stdin=None, **kwargs): + proc = subprocess.Popen(command, stdout=subprocess.PIPE, **kwargs) + 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 root, dirs, files in os.walk(dir or os.getcwd()): + if os.path.basename(root).startswith('.'): + del dirs[:] + continue + + for file in files: + if file.startswith('.'): + continue + elif file.endswith('.lib'): + with open(os.path.join(root, file)) as f: + yield f.read().strip(), os.path.join(root, file[:-4]) + if file[:-4] in dirs: + dirs.remove(file[:-4]) + +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, name=None): + repo = cls.__new__(cls) + + m = re.match('^(.*/([+a-zA-Z0-9_-]+)/?)(?:#(.*))?$', url) + repo.repo = m.group(1) + repo.name = name or 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 [('hg', '.hg'), ('git', '.git')]: + 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', 'name?', + help='recursively import a repository') +def import_(url, name=None): + repo = Repo.fromurl(url, name) + + for type in ['hg', 'git']: + try: + popen([type, 'clone', repo.repo, repo.path]) + 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 url, lib in iterlibs(): + import_(url, lib) + +# Deploy command +@subcommand('deploy', + help='recursively import libraries in current directory') +def deploy(): + for url, lib in iterlibs(): + import_(url, lib) + +# Install/uninstall command +@subcommand('add', 'url', 'name?', + help='add a library to the current repository') +def add(url, name): + cwd = Repo() + repo = Repo.fromurl(url, name) + + import_(url) + + repo.update() + savelib(repo) + + popen([cwd.type, 'add', repo.lib]) + +@subcommand('remove', 'library', + help='remove a library from the current repository folder') +def remove(library): + cwd = Repo() + repo = Repo(library) + + popen([cwd.type, 'rm', '-f', repo.lib]) + if cwd.type == 'hg': + os.remove(repo.lib) + + shutil.rmtree(repo.path) + +# Publish command +@subcommand('publish', + help='recursively publish changes to remote repositories') +def publish(): + cwd = Repo() + + for url, lib in iterlibs(): + if os.path.isdir(lib): + with cd(lib): + publish() + +# if cwd.type == 'git': +# if pquery(['git' +# +# if (cwd.type == 'git' and pquery(['git', 'diff', '--name-only', 'HEAD'])) + print 'DONT WORK YET' + +# Synch command +@subcommand('synch', + help='synchronize lib files') +def synch(): + cwd = Repo() + + for url, lib in iterlibs(): + repo = Repo.fromurl(url, lib) + repo.update() + if lib == repo.url: + continue + + savelib(repo) + + if cwd.type == 'git': + popen([cwd.type, 'add', repo.lib]) + +# Compile command +@subcommand('compile', 'args*', + help='compile project using workspace_tools') +def compile(args): + cwd = Repo() + + if not os.path.isdir('mbed-os'): + sys.stderr.write('Warning! mbed-os not found?') + sys.exit(-1) + + if not os.path.isfile('mbed_settings.py'): + shutil.copy('mbed-os/tools/settings.py', 'mbed_settings.py') + + if os.path.isfile('MACROS.txt'): + with open('MACROS.txt') as f: + macros = f.read().splitlines() + + env = os.environ.copy() + env['PYTHONPATH'] = '.' + popen(['python', 'mbed-os/tools/make.py'] + + list(chain.from_iterable(izip(repeat('-D'), macros))) + + ['--source=%s' % cwd.path, + '--build=%s' % os.path.join(cwd.path, '.build')] + + args, + env=env) + +# Export command +@subcommand('export', 'args*', + help='generate project files') +def export(args): + cwd = Repo() + + if not os.path.isdir('mbed-os'): + sys.stderr.write('Warning! mbed-os not found?') + sys.exit(-1) + + if not os.path.isfile('mbed_settings.py'): + shutil.copy('mbed-os/tools/settings.py', 'mbed_settings.py') + + popen(['python', 'mbed-os/tools/project.py', + '--source=%s' % cwd.path]) + +# Parse/run command +args, remainder = parser.parse_known_args() +status = args.command(args) +sys.exit(status or 0) +