Morpheus / Mbed OS mbed-Client-Morpheus-hg

Dependencies:   mbed-os

Committer:
Christopher Haster
Date:
Wed Mar 30 19:46:06 2016 -0500
Revision:
62:d6a6204fb327
Parent:
61:5c3f41de9d97
Parent:
60:52dc8fcb07d8
Child:
63:3b00ba456e00
Merged changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 15:a6b1f4e65bf4 1 #!/usr/bin/env python
Christopher Haster 15:a6b1f4e65bf4 2
Christopher Haster 15:a6b1f4e65bf4 3 import argparse
Christopher Haster 15:a6b1f4e65bf4 4 import sys
Christopher Haster 15:a6b1f4e65bf4 5 import re
Christopher Haster 15:a6b1f4e65bf4 6 import subprocess
Christopher Haster 15:a6b1f4e65bf4 7 import os
Christopher Haster 15:a6b1f4e65bf4 8 import contextlib
Christopher Haster 15:a6b1f4e65bf4 9 import shutil
Christopher Haster 35:ffcfa5ace437 10 from collections import *
Christopher Haster 15:a6b1f4e65bf4 11 from itertools import *
Christopher Haster 15:a6b1f4e65bf4 12
screamer 47:386f8c519142 13 # Default paths to Mercurial and Git
Christopher Haster 50:3770a8991c11 14 hg_cmd = 'hg'
Christopher Haster 50:3770a8991c11 15 git_cmd = 'git'
screamer 47:386f8c519142 16
Christopher Haster 15:a6b1f4e65bf4 17 # Subparser handling
Christopher Haster 15:a6b1f4e65bf4 18 parser = argparse.ArgumentParser()
Christopher Haster 15:a6b1f4e65bf4 19 subparsers = parser.add_subparsers()
Christopher Haster 15:a6b1f4e65bf4 20
Christopher Haster 15:a6b1f4e65bf4 21 def subcommand(name, *args, **kwargs):
Christopher Haster 15:a6b1f4e65bf4 22 def subcommand(command):
Christopher Haster 15:a6b1f4e65bf4 23 subparser = subparsers.add_parser(name, **kwargs)
Christopher Haster 15:a6b1f4e65bf4 24
Christopher Haster 15:a6b1f4e65bf4 25 for arg in args:
Christopher Haster 15:a6b1f4e65bf4 26 if arg.endswith('?'):
Christopher Haster 15:a6b1f4e65bf4 27 subparser.add_argument(arg.strip('?'), nargs='?')
Christopher Haster 15:a6b1f4e65bf4 28 elif arg.endswith('*'):
Christopher Haster 15:a6b1f4e65bf4 29 pass
Christopher Haster 15:a6b1f4e65bf4 30 else:
Christopher Haster 15:a6b1f4e65bf4 31 subparser.add_argument(arg)
Christopher Haster 15:a6b1f4e65bf4 32
Christopher Haster 15:a6b1f4e65bf4 33 def thunk(parsed_args):
Christopher Haster 15:a6b1f4e65bf4 34 ordered_args = [vars(parsed_args)[arg.strip('?*')]
Christopher Haster 15:a6b1f4e65bf4 35 if not arg.endswith('*') else remainder
Christopher Haster 15:a6b1f4e65bf4 36 for arg in args]
Christopher Haster 15:a6b1f4e65bf4 37 return command(*ordered_args)
Christopher Haster 15:a6b1f4e65bf4 38
Christopher Haster 15:a6b1f4e65bf4 39 subparser.set_defaults(command=thunk)
Christopher Haster 15:a6b1f4e65bf4 40 return command
Christopher Haster 15:a6b1f4e65bf4 41 return subcommand
Christopher Haster 15:a6b1f4e65bf4 42
Christopher Haster 15:a6b1f4e65bf4 43 # Process execution
Christopher Haster 15:a6b1f4e65bf4 44 class ProcessException(Exception):
Christopher Haster 15:a6b1f4e65bf4 45 pass
Christopher Haster 15:a6b1f4e65bf4 46
Christopher Haster 15:a6b1f4e65bf4 47 def popen(command, stdin=None, **kwargs):
Christopher Haster 15:a6b1f4e65bf4 48 # print for debugging
Christopher Haster 15:a6b1f4e65bf4 49 print ' '.join(command)
Christopher Haster 15:a6b1f4e65bf4 50 proc = subprocess.Popen(command, **kwargs)
Christopher Haster 15:a6b1f4e65bf4 51
Christopher Haster 15:a6b1f4e65bf4 52 if proc.wait() != 0:
Christopher Haster 15:a6b1f4e65bf4 53 raise ProcessException(proc.returncode)
Christopher Haster 15:a6b1f4e65bf4 54
Christopher Haster 15:a6b1f4e65bf4 55 def pquery(command, stdin=None, **kwargs):
Christopher Haster 15:a6b1f4e65bf4 56 proc = subprocess.Popen(command, stdout=subprocess.PIPE, **kwargs)
Christopher Haster 15:a6b1f4e65bf4 57 stdout, _ = proc.communicate(stdin)
Christopher Haster 15:a6b1f4e65bf4 58
Christopher Haster 15:a6b1f4e65bf4 59 if proc.returncode != 0:
Christopher Haster 15:a6b1f4e65bf4 60 raise ProcessException(proc.returncode)
Christopher Haster 15:a6b1f4e65bf4 61
Christopher Haster 15:a6b1f4e65bf4 62 return stdout
Christopher Haster 15:a6b1f4e65bf4 63
Christopher Haster 15:a6b1f4e65bf4 64 # Directory navigation
Christopher Haster 15:a6b1f4e65bf4 65 @contextlib.contextmanager
Christopher Haster 15:a6b1f4e65bf4 66 def cd(newdir):
Christopher Haster 15:a6b1f4e65bf4 67 prevdir = os.getcwd()
Christopher Haster 15:a6b1f4e65bf4 68 os.chdir(newdir)
Christopher Haster 15:a6b1f4e65bf4 69 try:
Christopher Haster 15:a6b1f4e65bf4 70 yield
Christopher Haster 15:a6b1f4e65bf4 71 finally:
Christopher Haster 15:a6b1f4e65bf4 72 os.chdir(prevdir)
Christopher Haster 15:a6b1f4e65bf4 73
Christopher Haster 15:a6b1f4e65bf4 74 # Handling for multiple version controls
Christopher Haster 35:ffcfa5ace437 75 scms = OrderedDict()
Christopher Haster 35:ffcfa5ace437 76 def scm(name):
Christopher Haster 35:ffcfa5ace437 77 def scm(cls):
Christopher Haster 35:ffcfa5ace437 78 scms[name] = cls()
Christopher Haster 35:ffcfa5ace437 79 return cls
Christopher Haster 35:ffcfa5ace437 80 return scm
Christopher Haster 35:ffcfa5ace437 81
Christopher Haster 35:ffcfa5ace437 82 def staticclass(cls):
Christopher Haster 35:ffcfa5ace437 83 for k, v in cls.__dict__.items():
Christopher Haster 36:5f4546dde73b 84 if hasattr(v, '__call__') and not k.startswith('__'):
Christopher Haster 35:ffcfa5ace437 85 setattr(cls, k, staticmethod(v))
Christopher Haster 35:ffcfa5ace437 86
Christopher Haster 35:ffcfa5ace437 87 return cls
Christopher Haster 35:ffcfa5ace437 88
Christopher Haster 35:ffcfa5ace437 89 @scm('hg')
Christopher Haster 35:ffcfa5ace437 90 @staticclass
Christopher Haster 35:ffcfa5ace437 91 class Hg(object):
Christopher Haster 35:ffcfa5ace437 92 def clone(url, name=None, hash=None):
screamer 47:386f8c519142 93 popen([hg_cmd, 'clone', url, name] + (['-u', hash] if hash else []))
Christopher Haster 35:ffcfa5ace437 94
screamer 47:386f8c519142 95 def add(file): popen([hg_cmd, 'add', file])
Christopher Haster 35:ffcfa5ace437 96 def remove(file):
screamer 47:386f8c519142 97 popen([hg_cmd, 'rm', '-f', file])
Christopher Haster 35:ffcfa5ace437 98 try:
Christopher Haster 35:ffcfa5ace437 99 os.remove(file)
Christopher Haster 35:ffcfa5ace437 100 except OSError:
Christopher Haster 35:ffcfa5ace437 101 pass
Christopher Haster 35:ffcfa5ace437 102
screamer 47:386f8c519142 103 def commit(): popen([hg_cmd, 'commit'])
screamer 47:386f8c519142 104 def push(): popen([hg_cmd, 'push'])
Christopher Haster 35:ffcfa5ace437 105 def pull(hash=None):
screamer 47:386f8c519142 106 popen([hg_cmd, 'pull'])
screamer 47:386f8c519142 107 popen([hg_cmd, 'update'] + (['-r', hash] if hash else []))
Christopher Haster 35:ffcfa5ace437 108
screamer 47:386f8c519142 109 def hash(): return pquery([hg_cmd, 'id', '-i']).strip().strip('+')
screamer 47:386f8c519142 110 def dirty(): return pquery([hg_cmd, 'status', '-q'])
Christopher Haster 35:ffcfa5ace437 111
Christopher Haster 44:5ff277e7f754 112 def ignore(file):
Christopher Haster 52:25da1dfebd7a 113 hooked = False
Christopher Haster 52:25da1dfebd7a 114 hook = 'ignore.local = .hg/hgignore'
Christopher Haster 52:25da1dfebd7a 115 with open('.hg/hgrc') as f:
Christopher Haster 52:25da1dfebd7a 116 if hook not in f.read().splitlines():
Christopher Haster 52:25da1dfebd7a 117 with open('.hg/hgrc', 'a') as f:
Christopher Haster 52:25da1dfebd7a 118 f.write('[ui]\n')
Christopher Haster 52:25da1dfebd7a 119 f.write(hook + '\n')
Christopher Haster 52:25da1dfebd7a 120
Christopher Haster 44:5ff277e7f754 121 file = '^%s/' % file
screamer 46:915be4b5a8f0 122 exclude = '.hg/hgignore'
Christopher Haster 42:58b35941ebd0 123 with open(exclude, 'a') as f:
Christopher Haster 44:5ff277e7f754 124 f.write(file + '\n')
Christopher Haster 42:58b35941ebd0 125
Christopher Haster 44:5ff277e7f754 126 def unignore(file):
Christopher Haster 44:5ff277e7f754 127 file = '^%s/' % file
screamer 46:915be4b5a8f0 128 exclude = '.hg/hgignore'
Christopher Haster 42:58b35941ebd0 129 if not os.path.isfile(exclude):
Christopher Haster 42:58b35941ebd0 130 return
Christopher Haster 42:58b35941ebd0 131
Christopher Haster 42:58b35941ebd0 132 with open(exclude) as f:
Christopher Haster 42:58b35941ebd0 133 lines = f.read().splitlines()
Christopher Haster 42:58b35941ebd0 134
Christopher Haster 44:5ff277e7f754 135 if file not in lines:
Christopher Haster 42:58b35941ebd0 136 return
Christopher Haster 42:58b35941ebd0 137
Christopher Haster 44:5ff277e7f754 138 lines.remove(file)
Christopher Haster 42:58b35941ebd0 139
Christopher Haster 42:58b35941ebd0 140 with open(exclude, 'w') as f:
Christopher Haster 42:58b35941ebd0 141 f.write('\n'.join(lines) + '\n')
Christopher Haster 42:58b35941ebd0 142
Christopher Haster 35:ffcfa5ace437 143 @scm('git')
Christopher Haster 35:ffcfa5ace437 144 @staticclass
Christopher Haster 35:ffcfa5ace437 145 class Git(object):
Christopher Haster 35:ffcfa5ace437 146 def clone(url, name=None, hash=None):
screamer 47:386f8c519142 147 popen([git_cmd, 'clone', url, name])
Christopher Haster 35:ffcfa5ace437 148 if hash:
Christopher Haster 39:8d6f31570710 149 with cd(name):
screamer 47:386f8c519142 150 popen([git_cmd, 'checkout', '-q', hash])
Christopher Haster 35:ffcfa5ace437 151
screamer 47:386f8c519142 152 def add(file): popen([git_cmd, 'add', file])
screamer 47:386f8c519142 153 def remove(file): popen([git_cmd, 'rm', '-f', file])
Christopher Haster 39:8d6f31570710 154
screamer 47:386f8c519142 155 def commit(): popen([git_cmd, 'commit', '-a'])
screamer 47:386f8c519142 156 def push(): popen([git_cmd, 'push', '--all'])
Christopher Haster 39:8d6f31570710 157 def pull(hash=None):
screamer 47:386f8c519142 158 popen([git_cmd, 'fetch', 'origin'])
screamer 47:386f8c519142 159 popen([git_cmd, 'merge'] + ([hash] if hash else []))
Christopher Haster 35:ffcfa5ace437 160
screamer 47:386f8c519142 161 def hash(): return pquery([git_cmd, 'rev-parse', '--short', 'HEAD']).strip()
screamer 47:386f8c519142 162 def dirty(): return pquery([git_cmd, 'diff', '--name-only', 'HEAD'])
Christopher Haster 40:2446665dfdf8 163
Christopher Haster 44:5ff277e7f754 164 def ignore(file):
Christopher Haster 42:58b35941ebd0 165 exclude = '.git/info/exclude'
Christopher Haster 42:58b35941ebd0 166 with open(exclude, 'a') as f:
Christopher Haster 44:5ff277e7f754 167 f.write(file + '\n')
Christopher Haster 42:58b35941ebd0 168
Christopher Haster 44:5ff277e7f754 169 def unignore(file):
Christopher Haster 42:58b35941ebd0 170 exclude = '.git/info/exclude'
Christopher Haster 42:58b35941ebd0 171 if not os.path.isfile(exclude):
Christopher Haster 42:58b35941ebd0 172 return
Christopher Haster 42:58b35941ebd0 173
Christopher Haster 42:58b35941ebd0 174 with open(exclude) as f:
Christopher Haster 42:58b35941ebd0 175 lines = f.read().splitlines()
Christopher Haster 42:58b35941ebd0 176
Christopher Haster 44:5ff277e7f754 177 if file not in lines:
Christopher Haster 42:58b35941ebd0 178 return
Christopher Haster 42:58b35941ebd0 179
Christopher Haster 44:5ff277e7f754 180 lines.remove(file)
Christopher Haster 42:58b35941ebd0 181
Christopher Haster 42:58b35941ebd0 182 with open(exclude, 'w') as f:
Christopher Haster 42:58b35941ebd0 183 f.write('\n'.join(lines) + '\n')
Christopher Haster 40:2446665dfdf8 184
Christopher Haster 35:ffcfa5ace437 185
Christopher Haster 35:ffcfa5ace437 186 # Repository object
Christopher Haster 15:a6b1f4e65bf4 187 class Repo(object):
Christopher Haster 36:5f4546dde73b 188 @classmethod
Christopher Haster 36:5f4546dde73b 189 def fromurl(cls, url, path=None):
Christopher Haster 36:5f4546dde73b 190 repo = cls()
Christopher Haster 36:5f4546dde73b 191
Christopher Haster 54:3cb9f99bbaaa 192 m = re.match('^(.*/([\w+-]+)(?:\.\w+)?)/?(?:#(.*))?$', url.strip())
Christopher Haster 36:5f4546dde73b 193 repo.name = os.path.basename(path or m.group(2))
Christopher Haster 36:5f4546dde73b 194 repo.path = os.path.abspath(
Christopher Haster 36:5f4546dde73b 195 path or os.path.join(os.getcwd(), repo.name))
Christopher Haster 36:5f4546dde73b 196
Christopher Haster 36:5f4546dde73b 197 repo.repo = m.group(1)
Christopher Haster 36:5f4546dde73b 198 repo.hash = m.group(3)
Christopher Haster 36:5f4546dde73b 199 return repo
Christopher Haster 15:a6b1f4e65bf4 200
Christopher Haster 15:a6b1f4e65bf4 201 @classmethod
Christopher Haster 36:5f4546dde73b 202 def fromlib(cls, lib=None):
Christopher Haster 36:5f4546dde73b 203 assert lib.endswith('.lib')
Christopher Haster 36:5f4546dde73b 204 with open(lib) as f:
Christopher Haster 36:5f4546dde73b 205 return cls.fromurl(f.read(), lib[:-4])
Christopher Haster 15:a6b1f4e65bf4 206
Christopher Haster 36:5f4546dde73b 207 @classmethod
Christopher Haster 36:5f4546dde73b 208 def fromrepo(cls, path=None):
Christopher Haster 36:5f4546dde73b 209 repo = cls()
Christopher Haster 36:5f4546dde73b 210 repo.path = os.path.abspath(path or os.getcwd())
Christopher Haster 36:5f4546dde73b 211 repo.name = os.path.basename(repo.path)
Christopher Haster 15:a6b1f4e65bf4 212
Christopher Haster 36:5f4546dde73b 213 repo.synch()
Christopher Haster 15:a6b1f4e65bf4 214 return repo
Christopher Haster 15:a6b1f4e65bf4 215
Christopher Haster 15:a6b1f4e65bf4 216 @property
Christopher Haster 15:a6b1f4e65bf4 217 def lib(self):
Christopher Haster 15:a6b1f4e65bf4 218 return self.path + '.lib'
Christopher Haster 15:a6b1f4e65bf4 219
Christopher Haster 15:a6b1f4e65bf4 220 @property
Christopher Haster 15:a6b1f4e65bf4 221 def url(self):
Christopher Haster 15:a6b1f4e65bf4 222 if self.repo:
screamer 60:52dc8fcb07d8 223 return self.repo + '/' + ('#'+self.hash if self.hash else '')
Christopher Haster 15:a6b1f4e65bf4 224
Christopher Haster 36:5f4546dde73b 225 def synch(self):
Christopher Haster 15:a6b1f4e65bf4 226 if os.path.isdir(self.path):
Christopher Haster 39:8d6f31570710 227 try:
Christopher Haster 39:8d6f31570710 228 self.scm = self.getscm()
Christopher Haster 39:8d6f31570710 229 self.hash = self.gethash()
Christopher Haster 39:8d6f31570710 230 self.libs = list(self.getlibs())
Christopher Haster 39:8d6f31570710 231 except ProcessException:
Christopher Haster 39:8d6f31570710 232 pass
Christopher Haster 15:a6b1f4e65bf4 233
Christopher Haster 37:bf73ffd98cca 234 if os.path.isfile(self.lib):
Christopher Haster 39:8d6f31570710 235 try:
Christopher Haster 39:8d6f31570710 236 self.repo = self.getrepo()
Christopher Haster 39:8d6f31570710 237 except ProcessException:
Christopher Haster 39:8d6f31570710 238 pass
Christopher Haster 37:bf73ffd98cca 239
Christopher Haster 35:ffcfa5ace437 240 def getscm(self):
Christopher Haster 36:5f4546dde73b 241 for name, scm in scms.items():
Christopher Haster 36:5f4546dde73b 242 if os.path.isdir(os.path.join(self.path, '.'+name)):
Christopher Haster 36:5f4546dde73b 243 return scm
Christopher Haster 35:ffcfa5ace437 244
Christopher Haster 15:a6b1f4e65bf4 245 def gethash(self):
Christopher Haster 15:a6b1f4e65bf4 246 with cd(self.path):
Christopher Haster 35:ffcfa5ace437 247 return self.scm.hash()
Christopher Haster 15:a6b1f4e65bf4 248
Christopher Haster 36:5f4546dde73b 249 def getlibs(self):
Christopher Haster 36:5f4546dde73b 250 for root, dirs, files in os.walk(self.path):
Christopher Haster 36:5f4546dde73b 251 dirs[:] = [d for d in dirs if not d.startswith('.')]
Christopher Haster 36:5f4546dde73b 252 files[:] = [f for f in files if not f.startswith('.')]
Christopher Haster 36:5f4546dde73b 253
Christopher Haster 36:5f4546dde73b 254 for file in files:
Christopher Haster 36:5f4546dde73b 255 if file.endswith('.lib'):
Christopher Haster 36:5f4546dde73b 256 yield Repo.fromlib(os.path.join(root, file))
Christopher Haster 49:977ea8d3e661 257 if file[:-4] in dirs:
Christopher Haster 49:977ea8d3e661 258 dirs.remove(file[:-4])
Christopher Haster 36:5f4546dde73b 259
Christopher Haster 37:bf73ffd98cca 260 def getrepo(self):
Christopher Haster 37:bf73ffd98cca 261 with open(self.lib) as f:
Christopher Haster 37:bf73ffd98cca 262 return Repo.fromurl(f.read()).repo
Christopher Haster 37:bf73ffd98cca 263
Christopher Haster 36:5f4546dde73b 264 def write(self):
Christopher Haster 38:0ca5eea23af9 265 if os.path.isfile(self.lib):
Christopher Haster 38:0ca5eea23af9 266 with open(self.lib) as f:
Christopher Haster 38:0ca5eea23af9 267 if f.read().strip() == self.url.strip():
Christopher Haster 44:5ff277e7f754 268 print self.name, 'unmodified'
Christopher Haster 38:0ca5eea23af9 269 return
Christopher Haster 36:5f4546dde73b 270
Christopher Haster 38:0ca5eea23af9 271 with open(self.lib, 'w') as f:
Christopher Haster 38:0ca5eea23af9 272 f.write(self.url + '\n')
Christopher Haster 36:5f4546dde73b 273
Christopher Haster 44:5ff277e7f754 274 print self.name, '->', self.url
Christopher Haster 44:5ff277e7f754 275
Christopher Haster 15:a6b1f4e65bf4 276 # Clone command
Christopher Haster 15:a6b1f4e65bf4 277 @subcommand('import', 'url', 'name?',
Christopher Haster 15:a6b1f4e65bf4 278 help='recursively import a repository')
Christopher Haster 36:5f4546dde73b 279 def import_(url, path=None):
Christopher Haster 36:5f4546dde73b 280 repo = Repo.fromurl(url, path)
Christopher Haster 15:a6b1f4e65bf4 281
Christopher Haster 35:ffcfa5ace437 282 for scm in scms.values():
Christopher Haster 15:a6b1f4e65bf4 283 try:
Christopher Haster 35:ffcfa5ace437 284 scm.clone(repo.repo, repo.path, repo.hash)
Christopher Haster 15:a6b1f4e65bf4 285 break
Christopher Haster 35:ffcfa5ace437 286 except ProcessException:
Christopher Haster 15:a6b1f4e65bf4 287 pass
Christopher Haster 15:a6b1f4e65bf4 288
Christopher Haster 36:5f4546dde73b 289 repo.synch()
Christopher Haster 15:a6b1f4e65bf4 290
Christopher Haster 15:a6b1f4e65bf4 291 with cd(repo.path):
Christopher Haster 36:5f4546dde73b 292 for lib in repo.libs:
Christopher Haster 36:5f4546dde73b 293 import_(lib.url, lib.path)
Christopher Haster 42:58b35941ebd0 294 repo.scm.ignore(lib.path[len(repo.path)+1:])
Christopher Haster 15:a6b1f4e65bf4 295
Christopher Haster 19:6ace1080b8bb 296 if (not os.path.isfile('mbed_settings.py') and
Christopher Haster 19:6ace1080b8bb 297 os.path.isfile('mbed-os/tools/settings.py')):
screamer 30:dcc9ff39aee3 298 shutil.copy('mbed-os/tools/default_settings.py', 'mbed_settings.py')
Christopher Haster 19:6ace1080b8bb 299
Christopher Haster 15:a6b1f4e65bf4 300 # Deploy command
Christopher Haster 15:a6b1f4e65bf4 301 @subcommand('deploy',
Christopher Haster 15:a6b1f4e65bf4 302 help='recursively import libraries in current directory')
Christopher Haster 15:a6b1f4e65bf4 303 def deploy():
Christopher Haster 36:5f4546dde73b 304 repo = Repo.fromrepo()
Christopher Haster 36:5f4546dde73b 305 for lib in repo.libs:
Christopher Haster 36:5f4546dde73b 306 import_(lib.url, lib.path)
Christopher Haster 42:58b35941ebd0 307 repo.scm.ignore(lib.path[len(repo.path)+1:])
Christopher Haster 15:a6b1f4e65bf4 308
Christopher Haster 15:a6b1f4e65bf4 309 # Install/uninstall command
Christopher Haster 15:a6b1f4e65bf4 310 @subcommand('add', 'url', 'name?',
Christopher Haster 15:a6b1f4e65bf4 311 help='add a library to the current repository')
Christopher Haster 36:5f4546dde73b 312 def add(url, path=None):
Christopher Haster 36:5f4546dde73b 313 repo = Repo.fromrepo()
Christopher Haster 15:a6b1f4e65bf4 314
Christopher Haster 36:5f4546dde73b 315 lib = Repo.fromurl(url, path)
Christopher Haster 36:5f4546dde73b 316 import_(lib.url, lib.path)
Christopher Haster 42:58b35941ebd0 317 repo.scm.ignore(lib.path[len(repo.path)+1:])
Christopher Haster 36:5f4546dde73b 318 lib.synch()
Christopher Haster 15:a6b1f4e65bf4 319
Christopher Haster 36:5f4546dde73b 320 lib.write()
Christopher Haster 36:5f4546dde73b 321 repo.scm.add(lib.lib)
Christopher Haster 15:a6b1f4e65bf4 322
Christopher Haster 36:5f4546dde73b 323 @subcommand('remove', 'path',
Christopher Haster 15:a6b1f4e65bf4 324 help='remove a library from the current repository folder')
Christopher Haster 36:5f4546dde73b 325 def remove(path):
Christopher Haster 36:5f4546dde73b 326 repo = Repo.fromrepo()
Christopher Haster 36:5f4546dde73b 327 lib = Repo.fromrepo(path)
Christopher Haster 15:a6b1f4e65bf4 328
Christopher Haster 36:5f4546dde73b 329 repo.scm.remove(lib.lib)
Christopher Haster 36:5f4546dde73b 330 shutil.rmtree(lib.path)
Christopher Haster 42:58b35941ebd0 331 repo.scm.unignore(lib.path[len(repo.path)+1:])
Christopher Haster 15:a6b1f4e65bf4 332
Christopher Haster 15:a6b1f4e65bf4 333 # Publish command
Christopher Haster 15:a6b1f4e65bf4 334 @subcommand('publish',
Christopher Haster 15:a6b1f4e65bf4 335 help='recursively publish changes to remote repositories')
Christopher Haster 18:1b4252106474 336 def publish(always=True):
Christopher Haster 36:5f4546dde73b 337 repo = Repo.fromrepo()
Christopher Haster 36:5f4546dde73b 338 for lib in repo.libs:
Christopher Haster 36:5f4546dde73b 339 with cd(lib.path):
Christopher Haster 36:5f4546dde73b 340 publish(False)
Christopher Haster 36:5f4546dde73b 341 synch()
Christopher Haster 15:a6b1f4e65bf4 342
Christopher Haster 36:5f4546dde73b 343 dirty = repo.scm.dirty()
Christopher Haster 17:1e487c450f06 344
Christopher Haster 36:5f4546dde73b 345 if dirty:
Christopher Haster 36:5f4546dde73b 346 print 'Uncommitted changes in %s (%s)' % (repo.name, repo.path)
Christopher Haster 24:b29dad301edd 347 raw_input('Press enter to commit and push ')
Christopher Haster 36:5f4546dde73b 348 repo.scm.commit()
Christopher Haster 17:1e487c450f06 349
Christopher Haster 36:5f4546dde73b 350 if dirty or always:
Christopher Haster 18:1b4252106474 351 try:
Christopher Haster 36:5f4546dde73b 352 repo.scm.push()
Christopher Haster 18:1b4252106474 353 except ProcessException as e:
Christopher Haster 18:1b4252106474 354 sys.exit(e[0])
Christopher Haster 15:a6b1f4e65bf4 355
Christopher Haster 20:84d6e18cbc20 356 # Update command
Christopher Haster 20:84d6e18cbc20 357 @subcommand('update', 'ref?',
Christopher Haster 20:84d6e18cbc20 358 help='recursively updates libraries and current repository')
Christopher Haster 20:84d6e18cbc20 359 def update(ref=None):
Christopher Haster 36:5f4546dde73b 360 repo = Repo.fromrepo()
Christopher Haster 36:5f4546dde73b 361 repo.scm.pull(ref)
Christopher Haster 36:5f4546dde73b 362
Christopher Haster 36:5f4546dde73b 363 for lib in repo.libs:
Christopher Haster 37:bf73ffd98cca 364 if (not os.path.isfile(lib.lib) or
Christopher Haster 37:bf73ffd98cca 365 lib.repo != Repo.fromrepo(lib.path).repo):
Christopher Haster 36:5f4546dde73b 366 with cd(lib.path):
Christopher Haster 36:5f4546dde73b 367 if lib.cwd.dirty():
Christopher Haster 37:bf73ffd98cca 368 sys.stderr.write('Uncommitted changes in %s (%s)\n'
Christopher Haster 36:5f4546dde73b 369 % (lib.name, lib.path))
Christopher Haster 36:5f4546dde73b 370 sys.exit(1)
Christopher Haster 20:84d6e18cbc20 371
Christopher Haster 36:5f4546dde73b 372 shutil.rmtree(lib.path)
Christopher Haster 42:58b35941ebd0 373 repo.scm.unignore(lib.path[len(repo.path)+1:])
Christopher Haster 36:5f4546dde73b 374
Christopher Haster 36:5f4546dde73b 375 repo.synch()
Christopher Haster 36:5f4546dde73b 376
Christopher Haster 36:5f4546dde73b 377 for lib in repo.libs:
Christopher Haster 45:5a91306f7924 378 if os.path.isdir(lib.path):
Christopher Haster 45:5a91306f7924 379 with cd(lib.path):
Christopher Haster 45:5a91306f7924 380 update(lib.hash)
Christopher Haster 45:5a91306f7924 381 else:
Christopher Haster 42:58b35941ebd0 382 import_(lib.url, lib.path)
Christopher Haster 42:58b35941ebd0 383 repo.scm.ignore(lib.path[len(repo.path)+1:])
Christopher Haster 20:84d6e18cbc20 384
Christopher Haster 15:a6b1f4e65bf4 385 # Synch command
Christopher Haster 15:a6b1f4e65bf4 386 @subcommand('synch',
Christopher Haster 15:a6b1f4e65bf4 387 help='synchronize lib files')
Christopher Haster 15:a6b1f4e65bf4 388 def synch():
Christopher Haster 36:5f4546dde73b 389 repo = Repo.fromrepo()
Christopher Haster 36:5f4546dde73b 390 for lib in repo.libs:
Christopher Haster 36:5f4546dde73b 391 lib.synch()
Christopher Haster 43:8a4a902a0654 392 lib.write()
Christopher Haster 15:a6b1f4e65bf4 393
Christopher Haster 15:a6b1f4e65bf4 394 # Compile command
Christopher Haster 15:a6b1f4e65bf4 395 @subcommand('compile', 'args*',
Christopher Haster 15:a6b1f4e65bf4 396 help='compile project using workspace_tools')
Christopher Haster 15:a6b1f4e65bf4 397 def compile(args):
Christopher Haster 15:a6b1f4e65bf4 398 if not os.path.isdir('mbed-os'):
Christopher Haster 37:bf73ffd98cca 399 sys.stderr.write('Warning! mbed-os not found?\n')
Christopher Haster 15:a6b1f4e65bf4 400 sys.exit(-1)
Christopher Haster 15:a6b1f4e65bf4 401
Christopher Haster 40:2446665dfdf8 402 repo = Repo.fromrepo()
Christopher Haster 40:2446665dfdf8 403
Christopher Haster 21:1a3f920b6f07 404 macros = []
Christopher Haster 15:a6b1f4e65bf4 405 if os.path.isfile('MACROS.txt'):
Christopher Haster 15:a6b1f4e65bf4 406 with open('MACROS.txt') as f:
Christopher Haster 15:a6b1f4e65bf4 407 macros = f.read().splitlines()
Christopher Haster 15:a6b1f4e65bf4 408
Christopher Haster 15:a6b1f4e65bf4 409 env = os.environ.copy()
Christopher Haster 15:a6b1f4e65bf4 410 env['PYTHONPATH'] = '.'
Christopher Haster 15:a6b1f4e65bf4 411 popen(['python', 'mbed-os/tools/make.py']
Christopher Haster 15:a6b1f4e65bf4 412 + list(chain.from_iterable(izip(repeat('-D'), macros)))
Christopher Haster 36:5f4546dde73b 413 + ['--source=%s' % repo.path,
Christopher Haster 36:5f4546dde73b 414 '--build=%s' % os.path.join(repo.path, '.build')]
Christopher Haster 15:a6b1f4e65bf4 415 + args,
Christopher Haster 15:a6b1f4e65bf4 416 env=env)
Christopher Haster 15:a6b1f4e65bf4 417
Christopher Haster 15:a6b1f4e65bf4 418 # Export command
Christopher Haster 15:a6b1f4e65bf4 419 @subcommand('export', 'args*',
Christopher Haster 15:a6b1f4e65bf4 420 help='generate project files')
Christopher Haster 15:a6b1f4e65bf4 421 def export(args):
Christopher Haster 15:a6b1f4e65bf4 422 if not os.path.isdir('mbed-os'):
Christopher Haster 37:bf73ffd98cca 423 sys.stderr.write('Warning! mbed-os not found?\n')
Christopher Haster 15:a6b1f4e65bf4 424 sys.exit(-1)
Christopher Haster 15:a6b1f4e65bf4 425
Christopher Haster 40:2446665dfdf8 426 repo = Repo.fromrepo()
Christopher Haster 40:2446665dfdf8 427
Christopher Haster 41:59e9d808ee05 428 macros = []
Christopher Haster 41:59e9d808ee05 429 if os.path.isfile('MACROS.txt'):
Christopher Haster 41:59e9d808ee05 430 with open('MACROS.txt') as f:
Christopher Haster 41:59e9d808ee05 431 macros = f.read().splitlines()
Christopher Haster 41:59e9d808ee05 432
Christopher Haster 18:1b4252106474 433 env = os.environ.copy()
Christopher Haster 18:1b4252106474 434 env['PYTHONPATH'] = '.'
Christopher Haster 15:a6b1f4e65bf4 435 popen(['python', 'mbed-os/tools/project.py',
Christopher Haster 36:5f4546dde73b 436 '--source=%s' % repo.path]
Christopher Haster 41:59e9d808ee05 437 + list(chain.from_iterable(izip(repeat('-D'), macros)))
Christopher Haster 18:1b4252106474 438 + args,
Christopher Haster 18:1b4252106474 439 env=env)
Christopher Haster 15:a6b1f4e65bf4 440
Christopher Haster 61:5c3f41de9d97 441 @subcommand('list',
Christopher Haster 61:5c3f41de9d97 442 help='list repositories recursively')
Christopher Haster 61:5c3f41de9d97 443 def list_(prefix=''):
Christopher Haster 61:5c3f41de9d97 444 repo = Repo.fromrepo()
Christopher Haster 61:5c3f41de9d97 445 print prefix + repo.name, '(%s)' % repo.hash
Christopher Haster 61:5c3f41de9d97 446
Christopher Haster 61:5c3f41de9d97 447 for i, lib in enumerate(repo.libs):
Christopher Haster 61:5c3f41de9d97 448 if prefix:
Christopher Haster 61:5c3f41de9d97 449 nprefix = prefix[:-3] + ('| ' if prefix[-3] == '|' else ' ')
Christopher Haster 61:5c3f41de9d97 450 else:
Christopher Haster 61:5c3f41de9d97 451 nprefix = ''
Christopher Haster 61:5c3f41de9d97 452
Christopher Haster 61:5c3f41de9d97 453 nprefix += '|- ' if i < len(repo.libs)-1 else '`- '
Christopher Haster 61:5c3f41de9d97 454
Christopher Haster 61:5c3f41de9d97 455 with cd(lib.path):
Christopher Haster 61:5c3f41de9d97 456 list_(nprefix)
Christopher Haster 61:5c3f41de9d97 457
Christopher Haster 15:a6b1f4e65bf4 458 # Parse/run command
Christopher Haster 15:a6b1f4e65bf4 459 args, remainder = parser.parse_known_args()
Christopher Haster 15:a6b1f4e65bf4 460 status = args.command(args)
Christopher Haster 15:a6b1f4e65bf4 461 sys.exit(status or 0)
Christopher Haster 15:a6b1f4e65bf4 462