Mercurial > hg > truffle
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) |