comparison hgext/histedit.py @ 27086:5f5c7d9f4a08

histedit: constant-ify the constraints list Used a class as a namespace, and then wired up a classmethod to return all known constraints. I'm mostly happy with this, even though it's kind of weird for hg.
author Augie Fackler <augie@google.com>
date Mon, 23 Nov 2015 10:13:05 -0500
parents d50ff8f4891f
children 3a2fd83182fb
comparison
equal deleted inserted replaced
27085:d50ff8f4891f 27086:5f5c7d9f4a08
179 from mercurial.i18n import _ 179 from mercurial.i18n import _
180 180
181 cmdtable = {} 181 cmdtable = {}
182 command = cmdutil.command(cmdtable) 182 command = cmdutil.command(cmdtable)
183 183
184 class _constraints(object):
185 # aborts if there are multiple rules for one node
186 noduplicates = 'noduplicates'
187 # abort if the node does belong to edited stack
188 forceother = 'forceother'
189 # abort if the node doesn't belong to edited stack
190 noother = 'noother'
191
192 @classmethod
193 def known(cls):
194 return set([v for k, v in cls.__dict__.items() if k[0] != '_'])
195
184 # Note for extension authors: ONLY specify testedwith = 'internal' for 196 # Note for extension authors: ONLY specify testedwith = 'internal' for
185 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 197 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
186 # be specifying the version(s) of Mercurial they are tested with, or 198 # be specifying the version(s) of Mercurial they are tested with, or
187 # leave the attribute unspecified. 199 # leave the attribute unspecified.
188 testedwith = 'internal' 200 testedwith = 'internal'
334 raise error.Abort(_('unknown changeset %s listed') % rulehash[:12]) 346 raise error.Abort(_('unknown changeset %s listed') % rulehash[:12])
335 return cls(state, node) 347 return cls(state, node)
336 348
337 def constraints(self): 349 def constraints(self):
338 """Return a set of constrains that this action should be verified for 350 """Return a set of constrains that this action should be verified for
339
340 Available constraints:
341 noduplicates - aborts if there are multiple rules for one node
342 noother - abort if the node doesn't belong to edited stack
343 forceother - abort if the node does belong to edited stack
344 """ 351 """
345 352 return set([_constraints.noduplicates, _constraints.noother])
346 return set(['noduplicates', 'noother'])
347 353
348 def nodetoverify(self): 354 def nodetoverify(self):
349 """Returns a node associated with the action that will be used for 355 """Returns a node associated with the action that will be used for
350 verification purposes. 356 verification purposes.
351 357
646 replacements.append((ich, (n,))) 652 replacements.append((ich, (n,)))
647 return repo[n], replacements 653 return repo[n], replacements
648 654
649 class base(histeditaction): 655 class base(histeditaction):
650 def constraints(self): 656 def constraints(self):
651 return set(['forceother']) 657 return set([_constraints.forceother])
652 658
653 def run(self): 659 def run(self):
654 if self.repo['.'].node() != self.node: 660 if self.repo['.'].node() != self.node:
655 mergemod.update(self.repo, self.node, False, True, False) 661 mergemod.update(self.repo, self.node, False, True, False)
656 # branchmerge, force, partial) 662 # branchmerge, force, partial)
1085 """Verify that there exists exactly one edit rule per given changeset. 1091 """Verify that there exists exactly one edit rule per given changeset.
1086 1092
1087 Will abort if there are to many or too few rules, a malformed rule, 1093 Will abort if there are to many or too few rules, a malformed rule,
1088 or a rule on a changeset outside of the user-given range. 1094 or a rule on a changeset outside of the user-given range.
1089 """ 1095 """
1090 known_constraints = ['noother', 'noduplicates']
1091 parsed = [] 1096 parsed = []
1092 expected = set(c.hex() for c in ctxs) 1097 expected = set(c.hex() for c in ctxs)
1093 seen = set() 1098 seen = set()
1094 for r in rules: 1099 for r in rules:
1095 if ' ' not in r: 1100 if ' ' not in r:
1099 if verb not in actiontable or verb.startswith('_'): 1104 if verb not in actiontable or verb.startswith('_'):
1100 raise error.Abort(_('unknown action "%s"') % verb) 1105 raise error.Abort(_('unknown action "%s"') % verb)
1101 action = actiontable[verb].fromrule(state, rest) 1106 action = actiontable[verb].fromrule(state, rest)
1102 constraints = action.constraints() 1107 constraints = action.constraints()
1103 for constraint in constraints: 1108 for constraint in constraints:
1104 if constraint not in known_constraints: 1109 if constraint not in _constraints.known():
1105 error.Abort(_('unknown constraint "%s"') % constraint) 1110 error.Abort(_('unknown constraint "%s"') % constraint)
1106 1111
1107 nodetoverify = action.nodetoverify() 1112 nodetoverify = action.nodetoverify()
1108 if nodetoverify is not None: 1113 if nodetoverify is not None:
1109 ha = node.hex(nodetoverify) 1114 ha = node.hex(nodetoverify)
1110 if 'noother' in constraints and ha not in expected: 1115 if _constraints.noother in constraints and ha not in expected:
1111 raise error.Abort( 1116 raise error.Abort(
1112 _('may not use "%s" with changesets ' 1117 _('may not use "%s" with changesets '
1113 'other than the ones listed') % verb) 1118 'other than the ones listed') % verb)
1114 if 'forceother' in constraints and ha in expected: 1119 if _constraints.forceother in constraints and ha in expected:
1115 raise error.Abort( 1120 raise error.Abort(
1116 _('may not use "%s" with changesets ' 1121 _('may not use "%s" with changesets '
1117 'within the edited list') % verb) 1122 'within the edited list') % verb)
1118 if 'noduplicates' in constraints and ha in seen: 1123 if _constraints.noduplicates in constraints and ha in seen:
1119 raise error.Abort(_('duplicated command for changeset %s') % 1124 raise error.Abort(_('duplicated command for changeset %s') %
1120 ha[:12]) 1125 ha[:12])
1121 seen.add(ha) 1126 seen.add(ha)
1122 rest = ha 1127 rest = ha
1123 parsed.append([verb, rest]) 1128 parsed.append([verb, rest])