Morpheus / Mbed OS mbed-Client-Morpheus-hg

Dependencies:   mbed-os

Committer:
screamer
Date:
Fri Apr 01 14:02:41 2016 +0100
Revision:
63:3b00ba456e00
Parent:
62:d6a6204fb327
Child:
64:012dffea11fd
Updated logging and few other things in neo.py

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