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:
- 36:5f4546dde73b
- Parent:
- 35:ffcfa5ace437
- Child:
- 37:bf73ffd98cca
diff -r ffcfa5ace437 -r 5f4546dde73b neo.py
--- a/neo.py Wed Mar 30 10:51:38 2016 -0500
+++ b/neo.py Wed Mar 30 12:58:34 2016 -0500
@@ -67,28 +67,6 @@
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
scms = OrderedDict()
def scm(name):
@@ -99,7 +77,7 @@
def staticclass(cls):
for k, v in cls.__dict__.items():
- if not k.startswith('__'):
+ if hasattr(v, '__call__') and not k.startswith('__'):
setattr(cls, k, staticmethod(v))
return cls
@@ -125,7 +103,7 @@
popen(['hg', 'update'] + (['-r', hash] if hash else []))
def hash(): return pquery(['hg', 'id', '-i']).strip().strip('+')
- def modified(): return pquery(['hg', 'status', '-q'])
+ def dirty(): return pquery(['hg', 'status', '-q'])
@scm('git')
@staticclass
@@ -140,27 +118,37 @@
def commit(): popen(['git', 'commit', '-a'])
def hash(): return pquery(['git', 'rev-parse', '--short', 'HEAD']).strip()
- def modified(): return pquery(['git', 'diff', '--name-only', 'HEAD'])
+ def dirty(): return pquery(['git', 'diff', '--name-only', 'HEAD'])
# Repository object
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, path=None):
+ repo = cls()
+
+ m = re.match('^(.*/([+a-zA-Z0-9_-]+)/?)(?:#(.*))?$', url.strip())
+ repo.name = os.path.basename(path or m.group(2))
+ repo.path = os.path.abspath(
+ path or os.path.join(os.getcwd(), repo.name))
+
+ repo.repo = m.group(1)
+ repo.hash = m.group(3)
+ return repo
@classmethod
- def fromurl(cls, url, name=None):
- repo = cls.__new__(cls)
- url = url.strip()
+ def fromlib(cls, lib=None):
+ assert lib.endswith('.lib')
+ with open(lib) as f:
+ return cls.fromurl(f.read(), lib[:-4])
- 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)
+ @classmethod
+ def fromrepo(cls, path=None):
+ repo = cls()
+ repo.path = os.path.abspath(path or os.getcwd())
+ repo.name = os.path.basename(repo.path)
- repo.path = os.path.join(os.getcwd(), repo.name)
+ repo.synch()
return repo
@property
@@ -170,39 +158,47 @@
@property
def url(self):
if self.repo:
- if self.hash:
- return self.repo + '#' + self.hash
- else:
- return self.repo
+ return self.repo + ('#'+self.hash if self.hash else '')
- def update(self):
+ def synch(self):
if os.path.isdir(self.path):
- self.type = self.gettype()
self.scm = self.getscm()
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
+ self.libs = list(self.getlibs())
def getscm(self):
- return scms[self.type]
+ for name, scm in scms.items():
+ if os.path.isdir(os.path.join(self.path, '.'+name)):
+ return scm
def gethash(self):
with cd(self.path):
return self.scm.hash()
+ def getlibs(self):
+ for root, dirs, files in os.walk(self.path):
+ dirs[:] = [d for d in dirs if not d.startswith('.')]
+ files[:] = [f for f in files if not f.startswith('.')]
+
+ for file in files:
+ if file.endswith('.lib'):
+ yield Repo.fromlib(os.path.join(root, file))
+
+ def write(self):
+ print repo.name, '->', repo.url
+
+ with open(repo.lib) as f:
+ if f.read().strip() == repo.url.strip():
+ return
+
+ with open(repo.lib, 'w') as f:
+ f.write(repo.url + '\n')
+
# Clone command
@subcommand('import', 'url', 'name?',
help='recursively import a repository')
-def import_(url, name=None):
- repo = Repo.fromurl(url, name)
+def import_(url, path=None):
+ repo = Repo.fromurl(url, path)
for scm in scms.values():
try:
@@ -211,11 +207,11 @@
except ProcessException:
pass
- repo.update()
+ repo.synch()
with cd(repo.path):
- for url, lib in iterlibs():
- import_(url, lib)
+ for lib in repo.libs:
+ import_(lib.url, lib.path)
if (not os.path.isfile('mbed_settings.py') and
os.path.isfile('mbed-os/tools/settings.py')):
@@ -225,56 +221,52 @@
@subcommand('deploy',
help='recursively import libraries in current directory')
def deploy():
- for url, lib in iterlibs():
- import_(url, lib)
+ repo = Repo.fromrepo()
+ for lib in repo.libs:
+ import_(lib.url, lib.path)
# 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)
+def add(url, path=None):
+ repo = Repo.fromrepo()
- import_(url)
-
- repo.update()
- savelib(repo)
+ lib = Repo.fromurl(url, path)
+ import_(lib.url, lib.path)
+ lib.synch()
- repo.scm.add(repo.lib)
+ lib.write()
+ repo.scm.add(lib.lib)
-@subcommand('remove', 'library',
+@subcommand('remove', 'path',
help='remove a library from the current repository folder')
-def remove(library):
- cwd = Repo()
- repo = Repo(library)
+def remove(path):
+ repo = Repo.fromrepo()
+ lib = Repo.fromrepo(path)
- cwd.scm.remove(repo.lib)
- shutil.rmtree(repo.path)
+ repo.scm.remove(lib.lib)
+ shutil.rmtree(lib.path)
# Publish command
@subcommand('publish',
help='recursively publish changes to remote repositories')
def publish(always=True):
- cwd = Repo()
+ repo = Repo.fromrepo()
+ for lib in repo.libs:
+ with cd(lib.path):
+ publish(False)
+ synch()
- for url, lib in iterlibs():
- if os.path.isdir(lib):
- with cd(lib):
- publish(False)
-
- synch()
- modified = cwd.scm.modified()
+ dirty = repo.scm.dirty()
- if modified:
- print cwd.path
- print 'Uncommitted changes in %s' % cwd.name
+ if dirty:
+ print 'Uncommitted changes in %s (%s)' % (repo.name, repo.path)
raw_input('Press enter to commit and push ')
+ repo.scm.commit()
- cwd.scm.commit()
-
- if modified or always:
+ if dirty or always:
try:
- cwd.scm.push()
+ repo.scm.push()
except ProcessException as e:
sys.exit(e[0])
@@ -282,36 +274,42 @@
@subcommand('update', 'ref?',
help='recursively updates libraries and current repository')
def update(ref=None):
- cwd = Repo()
- cwd.scm.pull(ref)
+ repo = Repo.fromrepo()
+ repo.scm.pull(ref)
+
+ for lib in repo.libs:
+ if not os.path.isfile(lib.lib):
+ with cd(lib.path):
+ if lib.cwd.dirty():
+ sys.stderr.write('Uncommitted changes in %s (%s)'
+ % (lib.name, lib.path))
+ sys.exit(1)
- for url, lib in iterlibs():
- repo = Repo.fromurl(url, lib)
- if os.path.isdir(lib):
- with cd(repo.path):
- update(repo.hash)
+ shutil.rmtree(lib.path)
+
+ repo.synch()
+
+ for lib in repo.libs:
+ if os.path.isdir(lib.path):
+ with cd(lib.path):
+ update(lib.hash)
else:
- import_(url, lib)
+ import_(lib.url, lib.path)
# 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 url == repo.url:
- continue
-
- savelib(repo)
+ repo = Repo.fromrepo()
+ for lib in repo.libs:
+ lib.synch()
+ lib.save()
# Compile command
@subcommand('compile', 'args*',
help='compile project using workspace_tools')
def compile(args):
- cwd = Repo()
+ repo = Repo.fromrepo()
if not os.path.isdir('mbed-os'):
sys.stderr.write('Warning! mbed-os not found?')
@@ -326,8 +324,8 @@
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')]
+ + ['--source=%s' % repo.path,
+ '--build=%s' % os.path.join(repo.path, '.build')]
+ args,
env=env)
@@ -335,7 +333,7 @@
@subcommand('export', 'args*',
help='generate project files')
def export(args):
- cwd = Repo()
+ repo = Repo.fromrepo()
if not os.path.isdir('mbed-os'):
sys.stderr.write('Warning! mbed-os not found?')
@@ -344,7 +342,7 @@
env = os.environ.copy()
env['PYTHONPATH'] = '.'
popen(['python', 'mbed-os/tools/project.py',
- '--source=%s' % cwd.path]
+ '--source=%s' % repo.path]
+ args,
env=env)