histedit: get rid of state.rules
authorMateusz Kwapich <mitrandir@fb.com>
Wed, 02 Dec 2015 12:19:01 -0800
changeset 27208 994d8dced775
parent 27207 2d8dbeb2462c
child 27209 7fbab10f812f
histedit: get rid of state.rules Now we are using state.actions instead of state.rules everywhere.
hgext/histedit.py
--- a/hgext/histedit.py	Wed Dec 02 12:19:01 2015 -0800
+++ b/hgext/histedit.py	Wed Dec 02 12:19:01 2015 -0800
@@ -215,10 +215,10 @@
 """)
 
 class histeditstate(object):
-    def __init__(self, repo, parentctxnode=None, rules=None, keep=None,
+    def __init__(self, repo, parentctxnode=None, actions=None, keep=None,
             topmost=None, replacements=None, lock=None, wlock=None):
         self.repo = repo
-        self.rules = rules
+        self.actions = actions
         self.keep = keep
         self.topmost = topmost
         self.parentctxnode = parentctxnode
@@ -248,7 +248,9 @@
             parentctxnode, rules, keep, topmost, replacements, backupfile = data
 
         self.parentctxnode = parentctxnode
-        self.rules = rules
+        rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules])
+        actions = parserules(rules, self)
+        self.actions = actions
         self.keep = keep
         self.topmost = topmost
         self.replacements = replacements
@@ -260,10 +262,9 @@
         fp.write('%s\n' % node.hex(self.parentctxnode))
         fp.write('%s\n' % node.hex(self.topmost))
         fp.write('%s\n' % self.keep)
-        fp.write('%d\n' % len(self.rules))
-        for rule in self.rules:
-            fp.write('%s\n' % rule[0]) # action
-            fp.write('%s\n' % rule[1]) # remainder
+        fp.write('%d\n' % len(self.actions))
+        for action in self.actions:
+            fp.write('%s\n' % action.tostate())
         fp.write('%d\n' % len(self.replacements))
         for replacement in self.replacements:
             fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r)
@@ -328,13 +329,6 @@
     def inprogress(self):
         return self.repo.vfs.exists('histedit-state')
 
-    @property
-    def actions(self):
-        actions = []
-        for (act, rest) in self.rules:
-            actions.append(actiontable[act].fromrule(self, rest))
-        return actions
-
 
 class histeditaction(object):
     def __init__(self, state, node):
@@ -953,10 +947,11 @@
                 f = open(rules)
             rules = f.read()
             f.close()
-        rules = [l for l in (r.strip() for r in rules.splitlines())
-                 if l and not l.startswith('#')]
-        rules = verifyrules(rules, state, [repo[c] for [_a, c] in state.rules])
-        state.rules = rules
+        actions = parserules(rules, state)
+        ctxs = [repo[act.nodetoverify()] \
+                for act in state.actions if act.nodetoverify()]
+        verifyactions(actions, state, ctxs)
+        state.actions = actions
         state.write()
         return
     elif goal == 'abort':
@@ -1037,14 +1032,13 @@
                 f = open(rules)
             rules = f.read()
             f.close()
-        rules = [l for l in (r.strip() for r in rules.splitlines())
-                 if l and not l.startswith('#')]
-        rules = verifyrules(rules, state, ctxs)
+        actions = parserules(rules, state)
+        verifyactions(actions, state, ctxs)
 
         parentctxnode = repo[root].parents()[0].node()
 
         state.parentctxnode = parentctxnode
-        state.rules = rules
+        state.actions = actions
         state.topmost = topmost
         state.replacements = replacements
 
@@ -1062,12 +1056,10 @@
             zip(actions, actions[1:] + [None])):
         if action.verb == 'fold' and nextact and nextact.verb == 'fold':
             state.actions[idx].__class__ = _multifold
-            state.rules[idx] = '_multifold', action.nodetoverify() # TODO remove this
 
     while state.actions:
         state.write()
         actobj = state.actions.pop(0)
-        state.rules.pop(0) # TODO remove this
         ui.debug('histedit: processing %s %s\n' % (actobj.verb,\
                                                    actobj.torule()))
         parentctx, replacement_ = actobj.run()
@@ -1121,7 +1113,6 @@
     repo = state.repo
     if state.actions:
         actobj = state.actions.pop(0)
-        state.rules.pop(0) # TODO remove this
 
         if _isdirtywc(repo):
             actobj.continuedirty()
@@ -1171,23 +1162,33 @@
 
     return rules
 
-def verifyrules(rules, state, ctxs):
-    """Verify that there exists exactly one edit rule per given changeset.
-
-    Will abort if there are to many or too few rules, a malformed rule,
-    or a rule on a changeset outside of the user-given range.
-    """
-    parsed = []
-    expected = set(c.hex() for c in ctxs)
-    seen = set()
+def parserules(rules, state):
+    """Read the histedit rules string and return list of action objects """
+    rules = [l for l in (r.strip() for r in rules.splitlines())
+                if l and not l.startswith('#')]
+    actions = []
     for r in rules:
         if ' ' not in r:
             raise error.Abort(_('malformed line "%s"') % r)
         verb, rest = r.split(' ', 1)
 
-        if verb not in actiontable or verb.startswith('_'):
+        if verb not in actiontable:
             raise error.Abort(_('unknown action "%s"') % verb)
+
         action = actiontable[verb].fromrule(state, rest)
+        actions.append(action)
+    return actions
+
+def verifyactions(actions, state, ctxs):
+    """Verify that there exists exactly one action per given changeset and
+    other constraints.
+
+    Will abort if there are to many or too few rules, a malformed rule,
+    or a rule on a changeset outside of the user-given range.
+    """
+    expected = set(c.hex() for c in ctxs)
+    seen = set()
+    for action in actions:
         action.verify()
         constraints = action.constraints()
         for constraint in constraints:
@@ -1200,23 +1201,20 @@
             if _constraints.noother in constraints and ha not in expected:
                 raise error.Abort(
                     _('may not use "%s" with changesets '
-                      'other than the ones listed') % verb)
+                      'other than the ones listed') % action.verb)
             if _constraints.forceother in constraints and ha in expected:
                 raise error.Abort(
                     _('may not use "%s" with changesets '
-                      'within the edited list') % verb)
+                      'within the edited list') % action.verb)
             if _constraints.noduplicates in constraints and ha in seen:
                 raise error.Abort(_('duplicated command for changeset %s') %
                         ha[:12])
             seen.add(ha)
-            rest = ha
-        parsed.append([verb, rest])
     missing = sorted(expected - seen)  # sort to stabilize output
     if missing:
         raise error.Abort(_('missing rules for changeset %s') %
                 missing[0][:12],
                 hint=_('do you want to use the drop action?'))
-    return parsed
 
 def newnodestoabort(state):
     """process the list of replacements to return