comparison mxtool/mx.py @ 12512:21aa1ce5c666

made hg be called lazily
author Doug Simon <doug.simon@oracle.com>
date Tue, 22 Oct 2013 11:01:32 +0200
parents 5cde653f58f9
children bb665959fb12
comparison
equal deleted inserted replaced
12508:5cde653f58f9 12512:21aa1ce5c666
502 """ 502 """
503 Encapsulates access to Mercurial (hg) 503 Encapsulates access to Mercurial (hg)
504 """ 504 """
505 def __init__(self): 505 def __init__(self):
506 self.missing = 'no hg executable found' 506 self.missing = 'no hg executable found'
507 try: 507 self.has_hg = None
508 subprocess.check_output(['hg']) 508
509 self.has_hg = True 509 def check(self, abortOnFail=True):
510 except OSError: 510 if self.has_hg is None:
511 self.has_hg = False 511 try:
512 warn(self.missing) 512 subprocess.check_output(['hg'])
513 513 self.has_hg = True
514 def _check(self, abortOnFail=True): 514 except OSError:
515 self.has_hg = False
516 warn(self.missing)
517
515 if not self.has_hg: 518 if not self.has_hg:
516 if abortOnFail: 519 if abortOnFail:
517 abort(self.missing) 520 abort(self.missing)
518 else: 521 else:
519 warn(self.missing) 522 warn(self.missing)
520 return self.has_hg 523
521 524 def tip(self, s, abortOnError=True):
522 def _tip(self, s, abortOnError=True):
523 if not self.has_hg:
524 return None
525 try: 525 try:
526 version = subprocess.check_output(['hg', 'tip', '-R', s.dir, '--template', '{node}']) 526 version = subprocess.check_output(['hg', 'tip', '-R', s.dir, '--template', '{node}'])
527 if s.version is not None and s.version != version: 527 if s.version is not None and s.version != version:
528 abort('version of suite ' + s.name +' has changed during run') 528 abort('version of suite ' + s.name +' has changed during run')
529 return version 529 return version
530 except OSError:
531 warn(self.missing)
530 except subprocess.CalledProcessError: 532 except subprocess.CalledProcessError:
531 if abortOnError: 533 if abortOnError:
532 abort('failed to get tip revision id') 534 abort('failed to get tip revision id')
533 else: 535 else:
534 return None 536 return None
535 537
536 def _canpush(self, s, strict=True): 538 def can_push(self, s, strict=True):
537 try: 539 try:
538 output = subprocess.check_output(['hg', '-R', s.dir, 'status']) 540 output = subprocess.check_output(['hg', '-R', s.dir, 'status'])
539 # super strict 541 # super strict
540 return output == '' 542 return output == ''
543 except OSError:
544 warn(self.missing)
541 except subprocess.CalledProcessError: 545 except subprocess.CalledProcessError:
542 return False 546 return False
543 547
544 def _default_push(self, sdir): 548 def default_push(self, sdir):
545 with open(join(sdir, '.hg', 'hgrc')) as f: 549 with open(join(sdir, '.hg', 'hgrc')) as f:
546 for line in f: 550 for line in f:
547 line = line.rstrip() 551 line = line.rstrip()
548 if line.startswith('default = '): 552 if line.startswith('default = '):
549 return line[len('default = '):] 553 return line[len('default = '):]
761 self.dists = [] 765 self.dists = []
762 self.imports = [] 766 self.imports = []
763 self.commands = None 767 self.commands = None
764 self.primary = primary 768 self.primary = primary
765 self.name = _suitename(mxDir) # validated in _load_projects 769 self.name = _suitename(mxDir) # validated in _load_projects
766 self.version = None # _hg._tip checks current version if not None 770 self.version = None # _hg.tip checks current version if not None
767 self.version = _hg._tip(self, False) 771 self.version = _hg.tip(self, False)
768 if load: 772 if load:
769 # load suites bottom up to make sure command overriding works properly 773 # load suites bottom up to make sure command overriding works properly
770 self._load_imports() 774 self._load_imports()
771 self._load_env() 775 self._load_env()
772 self._load_commands() 776 self._load_commands()
3941 return kwargs.pop(0) 3945 return kwargs.pop(0)
3942 return None 3946 return None
3943 3947
3944 def sclone(args): 3948 def sclone(args):
3945 """clone a suite repository, and its imported suites""" 3949 """clone a suite repository, and its imported suites"""
3946 _hg._check(True) 3950 _hg.check(True)
3947 parser = ArgumentParser(prog='mx sclone') 3951 parser = ArgumentParser(prog='mx sclone')
3948 parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>') 3952 parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>')
3949 parser.add_argument('--dest', help='destination directory (default basename of source)', metavar='<path>') 3953 parser.add_argument('--dest', help='destination directory (default basename of source)', metavar='<path>')
3950 parser.add_argument("--no-imports", action='store_true', help='do not clone imported suites') 3954 parser.add_argument("--no-imports", action='store_true', help='do not clone imported suites')
3951 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') 3955 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
4027 _sclone(importee_source, importee_dest, suite_import.version, False) 4031 _sclone(importee_source, importee_dest, suite_import.version, False)
4028 # _clone handles the recursive visit of the new imports 4032 # _clone handles the recursive visit of the new imports
4029 4033
4030 def scloneimports(args): 4034 def scloneimports(args):
4031 """clone the imports of an existing suite""" 4035 """clone the imports of an existing suite"""
4032 _hg._check(True) 4036 _hg.check(True)
4033 parser = ArgumentParser(prog='mx scloneimports') 4037 parser = ArgumentParser(prog='mx scloneimports')
4034 parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>') 4038 parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>')
4035 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') 4039 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
4036 args = parser.parse_args(args) 4040 args = parser.parse_args(args)
4037 # check for non keyword args 4041 # check for non keyword args
4041 if not os.path.isdir(args.source): 4045 if not os.path.isdir(args.source):
4042 abort(args.source + ' is not a directory') 4046 abort(args.source + ' is not a directory')
4043 4047
4044 s = _scloneimports_suitehelper(args.source) 4048 s = _scloneimports_suitehelper(args.source)
4045 4049
4046 default_path = _hg._default_push(args.source) 4050 default_path = _hg.default_push(args.source)
4047 4051
4048 if default_path is None: 4052 if default_path is None:
4049 abort('no default path in ' + join(args.source, '.hg', 'hgrc')) 4053 abort('no default path in ' + join(args.source, '.hg', 'hgrc'))
4050 4054
4051 # We can now set the primary dir for the dst suitemodel 4055 # We can now set the primary dir for the dst suitemodel
4060 dest = _dst_suitemodel._importee_dir(dest, suite_import.name) 4064 dest = _dst_suitemodel._importee_dir(dest, suite_import.name)
4061 _spush(suite(suite_import.name), suite_import, dest, checks, clonemissing) 4065 _spush(suite(suite_import.name), suite_import, dest, checks, clonemissing)
4062 4066
4063 def _spush_check_import_visitor(s, suite_import, **extra_args): 4067 def _spush_check_import_visitor(s, suite_import, **extra_args):
4064 """push check visitor for Suite._visit_imports""" 4068 """push check visitor for Suite._visit_imports"""
4065 currentTip = _hg._tip(suite(suite_import.name)) 4069 currentTip = _hg.tip(suite(suite_import.name))
4066 if currentTip != suite_import.version: 4070 if currentTip != suite_import.version:
4067 abort('import version of ' + suite_import.name + ' in suite ' + s.name + ' does not match tip') 4071 abort('import version of ' + suite_import.name + ' in suite ' + s.name + ' does not match tip')
4068 4072
4069 def _spush(s, suite_import, dest, checks, clonemissing): 4073 def _spush(s, suite_import, dest, checks, clonemissing):
4070 if checks: 4074 if checks:
4071 if not _hg._canpush(s): 4075 if not _hg.can_push(s):
4072 abort('working directory ' + s.dir + ' contains uncommitted changes, push aborted') 4076 abort('working directory ' + s.dir + ' contains uncommitted changes, push aborted')
4073 4077
4074 # check imports first 4078 # check imports first
4075 if checks: 4079 if checks:
4076 s._visit_imports(_spush_check_import_visitor) 4080 s._visit_imports(_spush_check_import_visitor)
4106 cmd.append(dest) 4110 cmd.append(dest)
4107 run(cmd) 4111 run(cmd)
4108 4112
4109 def spush(args): 4113 def spush(args):
4110 """push primary suite and all its imports""" 4114 """push primary suite and all its imports"""
4111 _hg._check(True) 4115 _hg.check(True)
4112 parser = ArgumentParser(prog='mx spush') 4116 parser = ArgumentParser(prog='mx spush')
4113 parser.add_argument('--dest', help='url/path of repo to push to (default as per hg push)', metavar='<path>') 4117 parser.add_argument('--dest', help='url/path of repo to push to (default as per hg push)', metavar='<path>')
4114 parser.add_argument('--no-checks', action='store_true', help='checks on status, versions are disabled') 4118 parser.add_argument('--no-checks', action='store_true', help='checks on status, versions are disabled')
4115 parser.add_argument('--clonemissing', action='store_true', help='clone missing imported repos at destination (forces --no-checks)') 4119 parser.add_argument('--clonemissing', action='store_true', help='clone missing imported repos at destination (forces --no-checks)')
4116 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') 4120 parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
4144 run(['hg', '-R', s.dir, 'update']) 4148 run(['hg', '-R', s.dir, 'update'])
4145 4149
4146 def supdate(args): 4150 def supdate(args):
4147 """update primary suite and all its imports""" 4151 """update primary suite and all its imports"""
4148 4152
4149 _hg._check(True) 4153 _hg.check(True)
4150 s = _check_primary_suite() 4154 s = _check_primary_suite()
4151 4155
4152 _supdate(s, None) 4156 _supdate(s, None)
4153 4157
4154 def _scheck_imports_visitor(s, suite_import, update_versions, updated_imports): 4158 def _scheck_imports_visitor(s, suite_import, update_versions, updated_imports):
4157 4161
4158 def _scheck_imports(s, suite_import, update_versions, updated_imports): 4162 def _scheck_imports(s, suite_import, update_versions, updated_imports):
4159 # check imports recursively 4163 # check imports recursively
4160 s._visit_imports(_scheck_imports_visitor, update_versions=update_versions) 4164 s._visit_imports(_scheck_imports_visitor, update_versions=update_versions)
4161 4165
4162 currentTip = _hg._tip(s) 4166 currentTip = _hg.tip(s)
4163 if currentTip != suite_import.version: 4167 if currentTip != suite_import.version:
4164 print('import version of ' + s.name + ' does not match tip' + (': updating' if update_versions else '')) 4168 print('import version of ' + s.name + ' does not match tip' + (': updating' if update_versions else ''))
4165 4169
4166 if update_versions: 4170 if update_versions:
4167 suite_import.version = currentTip 4171 suite_import.version = currentTip
4178 def _spull_import_visitor(s, suite_import, update_versions, updated_imports): 4182 def _spull_import_visitor(s, suite_import, update_versions, updated_imports):
4179 """pull visitor for Suite._visit_imports""" 4183 """pull visitor for Suite._visit_imports"""
4180 _spull(suite(suite_import.name), update_versions, updated_imports) 4184 _spull(suite(suite_import.name), update_versions, updated_imports)
4181 4185
4182 def _spull(s, update_versions, updated_imports): 4186 def _spull(s, update_versions, updated_imports):
4183 _hg._check(True) 4187 _hg.check(True)
4184 # pull imports first 4188 # pull imports first
4185 s._visit_imports(_spull_import_visitor, update_versions=update_versions) 4189 s._visit_imports(_spull_import_visitor, update_versions=update_versions)
4186 4190
4187 run(['hg', '-R', s.dir, 'pull', '-u']) 4191 run(['hg', '-R', s.dir, 'pull', '-u'])
4188 if update_versions and updated_imports is not None: 4192 if update_versions and updated_imports is not None:
4189 tip = _hg._tip(s) 4193 tip = _hg.tip(s)
4190 updated_imports.write(SuiteImport._tostring(s.name, tip) + '\n') 4194 updated_imports.write(SuiteImport._tostring(s.name, tip) + '\n')
4191 4195
4192 def spull(args): 4196 def spull(args):
4193 """pull primary suite and all its imports""" 4197 """pull primary suite and all its imports"""
4194 _hg._check(True) 4198 _hg.check(True)
4195 parser = ArgumentParser(prog='mx spull') 4199 parser = ArgumentParser(prog='mx spull')
4196 parser.add_argument('--update-versions', action='store_true', help='update version ids of imported suites') 4200 parser.add_argument('--update-versions', action='store_true', help='update version ids of imported suites')
4197 args = parser.parse_args(args) 4201 args = parser.parse_args(args)
4198 4202
4199 _spull(_check_primary_suite(), args.update_versions, None) 4203 _spull(_check_primary_suite(), args.update_versions, None)