state are now object.
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Wed, 25 May 2011 01:46:48 +0200
changeset 10 91169d2d7f1b
parent 9 1f84a74df837
child 11 47ba990eff0e
state are now object.
states.py
tests/test-private.t
--- a/states.py	Mon May 23 17:15:47 2011 +0200
+++ b/states.py	Wed May 25 01:46:48 2011 +0200
@@ -32,13 +32,52 @@
 from mercurial import wireproto
 
 
-_NOPULLPUSH=2
+_NOSHARE=2
 _MUTABLE=1
 
-STATES = (0, _MUTABLE, _NOPULLPUSH | _MUTABLE)
-def statename(state):
-    return str(STATES)
+class state(object):
+
+    def __init__(self, name, order=0, next=None):
+        self.name = name
+        self.order = order
+        assert next is None or self < next
+        self.next = next
+
+    def __repr__(self):
+        return 'state(%s)' % self.name
+
+    def __str__(self):
+        return self.name
+
+    @util.propertycache
+    def trackheads(self):
+        return self.next is not None
+
+    def __cmp__(self, other):
+        return cmp(self.order, other.order)
 
+    @util.propertycache
+    def _revsetheads(self):
+        assert self.trackheads
+        def revsetheads(repo, subset, x):
+            args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
+            heads = map(repo.changelog.rev, repo._statesheads[self])
+            heads.sort()
+            return heads
+        return revsetheads
+
+    @util.propertycache
+    def headssymbol(self):
+        if self.trackheads:
+            return "%sheads" % self.name
+        else:
+            return 'heads'
+
+STDRAFT = state('draft', _NOSHARE | _MUTABLE)
+STREADY = state('ready', _MUTABLE, next=STDRAFT)
+STPUBLISHED = state('published', next=STREADY)
+
+STATES = (STPUBLISHED, STREADY, STDRAFT)
 
 # util function
 #############################
@@ -62,34 +101,29 @@
 # New revset predicate
 #############################
 
-def revsetstatehead(state):
-    def revsetpublicheads(repo, subset, x):
-        args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
-        heads = map(repo.changelog.rev, repo._statesheads[state])
-        heads.sort()
-        return heads
-    return revsetpublicheads
 
 def extsetup(ui):
-    revset.symbols['frozenheads'] = revsetstatehead(0)
-    revset.symbols['publicheads'] = revsetstatehead(1)
-
-REVSETHEADS = {0: 'frozenheads()',
-               1: 'publicheads()'}
+    for state in STATES:
+        if state.trackheads:
+            revset.symbols[state.headssymbol] = state._revsetheads
 
 # New commands
 #############################
 
-def cmdsetstate(ui, repo, state, *changesets):
+def cmdsetstate(ui, repo, statename, *changesets):
     """turn private changesets into public ones"""
     #assert repo.ui.configbool('private', 'enable', False)
-    state = int(state) #for now
+    for state in STATES: # few states
+        if state.name == statename:
+            break
+    else:
+        raise util.Abort(_('unknown state: %s') % statename)
     revs = scmutil.revrange(repo, changesets)
     repo.setstate(state, [repo.changelog.node(rev) for rev in revs])
     return 0
 
 cmdtable = {
-    'setstate':  (cmdsetstate,   [], _('state <revset>')),
+    'setstate':  (cmdsetstate,   [], _('<state> <revset>')),
     }
 
 
@@ -148,13 +182,13 @@
         @property
         def _publicheads(self):
             if self.ui.configbool('states', 'private', False):
-                return self._statesheads[1]
+                return self._statesheads[STREADY]
             return self.heads()
 
         @property
         def _frozenheads(self):
             if self.ui.configbool('states', 'liquid', False):
-                return self._statesheads[O]
+                return self._statesheads[STPUBLISHED]
             return self.heads()
 
         @util.propertycache
@@ -175,8 +209,8 @@
             return heads
         def _readstatesheads(self):
             statesheads = {}
-            statesheads[0] = self._readheadsfile('frozenheads')
-            statesheads[1] = self._readheadsfile('publicheads')
+            statesheads[STPUBLISHED] = self._readheadsfile('frozenheads')
+            statesheads[STREADY] = self._readheadsfile('publicheads')
             return statesheads
 
         def _writeheadsfile(self, filename, heads):
@@ -190,8 +224,8 @@
 
         def _writestateshead(self):
             # transaction!
-            self._writeheadsfile('frozenheads', self._statesheads[0])
-            self._writeheadsfile('publicheads', self._statesheads[1])
+            self._writeheadsfile('frozenheads', self._statesheads[STPUBLISHED])
+            self._writeheadsfile('publicheads', self._statesheads[STREADY])
 
         def setstate(self, state, nodes):
             """freeze targets changeset and it's ancestors.
@@ -203,12 +237,12 @@
             heads[:] = set(heads)
             heads.sort()
             if olds != heads:
-                heads[:] = noderange(repo, ["heads(::%s)" % REVSETHEADS[state]])
+                heads[:] = noderange(repo, ["heads(::%s())" % state.headssymbol])
                 heads.sort()
             if olds != heads:
                 self._writestateshead()
-            if state < 1:
-                self.setstate(1, nodes) # cascading
+            if state.next is not None and state.next.trackheads:
+                self.setstate(state.next, nodes) # cascading
 
         def _reducehead(self, candidates):
             selected = set()
--- a/tests/test-private.t	Mon May 23 17:15:47 2011 +0200
+++ b/tests/test-private.t	Wed May 25 01:46:48 2011 +0200
@@ -16,8 +16,8 @@
   $ echo "la veille dame" > babar
   $ hg ci -m "add dame"
   $ hg log --template='{rev}:{node|short}: {state}\n'
-  1:710fe444b3b0: 0
-  0:5caa672bac26: 0
+  1:710fe444b3b0: published
+  0:5caa672bac26: published
   $ hg out  ../remote1 --template='{rev}:{node|short}\n'
   comparing with ../remote1
   searching for changes
@@ -30,17 +30,17 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 1 files
-  $ hg setstate 0 1 # until we fix push
+  $ hg setstate published 1 # until we fix push
   $ echo "tree" >> savanna
   $ hg add savanna
   $ hg ci -m "terrain"
   $ echo "flore" >> babar
   $ hg ci -m "children"
   $ hg log --template='{rev}:{node|short}: {state}\n'
-  3:73585b17392a: 0
-  2:3c8695235a32: 0
-  1:710fe444b3b0: 0
-  0:5caa672bac26: 0
+  3:73585b17392a: published
+  2:3c8695235a32: published
+  1:710fe444b3b0: published
+  0:5caa672bac26: published
 
 turn private on (repo side)
   $ cat > .hg/hgrc << EOF
@@ -48,10 +48,10 @@
   > private=yes
   > EOF
   $ hg log --template='{rev}:{node|short}: {state}\n'
-  3:73585b17392a: 3
-  2:3c8695235a32: 3
-  1:710fe444b3b0: 0
-  0:5caa672bac26: 0
+  3:73585b17392a: draft
+  2:3c8695235a32: draft
+  1:710fe444b3b0: published
+  0:5caa672bac26: published
 
 test outgoing and push
   $ hg out  ../remote1 --template='{rev}:{node|short}\n'
@@ -80,10 +80,10 @@
 turn private off again (repo side)
   $ sed -i 's/^private=.*$/private=no/' .hg/hgrc
   $ hg log --template='{rev}:{node|short}: {state}\n'
-  3:73585b17392a: 0
-  2:3c8695235a32: 0
-  1:710fe444b3b0: 0
-  0:5caa672bac26: 0
+  3:73585b17392a: published
+  2:3c8695235a32: published
+  1:710fe444b3b0: published
+  0:5caa672bac26: published
   $ hg out  ../remote1 --template='{rev}:{node|short}\n'
   comparing with ../remote1
   searching for changes