topics: add a config to reject draft changeset without topic on a server
authorPulkit Goyal <7895pulkit@gmail.com>
Sat, 09 Dec 2017 06:13:28 +0100
changeset 3235 8a772f0c54d9
parent 3234 a18ca224e812
child 3236 7c78b0c482a1
topics: add a config to reject draft changeset without topic on a server This patch adds a new config option experimental.topic-mode.server which if sets to True, the server won't accept any draft changeset without topic on it. In case both `experimental.topic-mode.server` and `experimental.topic.publish-bare-branch` are set to True, the enforce-topic one is respected. Tests are added for it. The CHANGELOG file is also updated mentioning about the config option.
CHANGELOG
hgext3rd/topic/__init__.py
hgext3rd/topic/flow.py
tests/test-topic-flow-reject-untopiced.t
--- a/CHANGELOG	Sat Dec 09 05:05:39 2017 +0100
+++ b/CHANGELOG	Sat Dec 09 06:13:28 2017 +0100
@@ -12,6 +12,8 @@
 
   * add a new 'serverminitopic' extension for minimal server support
     (see `hg help -e serverminitopic` for details)
+  * add a new config option `experimental.topic-mode.server` using which a
+    server can reject draft changesets without topic
 
 7.0.2 - in progress
 -------------------
--- a/hgext3rd/topic/__init__.py	Sat Dec 09 05:05:39 2017 +0100
+++ b/hgext3rd/topic/__init__.py	Sat Dec 09 06:13:28 2017 +0100
@@ -199,6 +199,9 @@
     configitem('_internal', 'keep-topic',
                default=False,
     )
+    configitem('experimental', 'topic-mode.server',
+               default=configitem.dynamicdefault,
+    )
 
     def extsetup(ui):
         # register config that strictly belong to other code (thg, core, etc)
@@ -223,6 +226,7 @@
         return ''
     return self.extra().get(constants.extrakey, '')
 context.basectx.topic = _contexttopic
+
 def _contexttopicidx(self):
     topic = self.topic()
     if not topic:
@@ -421,7 +425,19 @@
                     origvalidator(tr2)
                 tr.validator = validator
 
-            if (repo.ui.configbool('experimental', 'topic.publish-bare-branch')
+            topicmodeserver = repo.ui.config('experimental',
+                                             'topic-mode.server', 'ignore')
+            ispush = (desc.startswith('push') or desc.startswith('serve'))
+            if (topicmodeserver != 'ignore' and ispush):
+                origvalidator = tr.validator
+
+                def validator(tr2):
+                    repo = reporef()
+                    flow.rejectuntopicedchangeset(repo, tr2)
+                    return origvalidator(tr2)
+                tr.validator = validator
+
+            elif (repo.ui.configbool('experimental', 'topic.publish-bare-branch')
                     and (desc.startswith('push')
                          or desc.startswith('serve'))
                     ):
--- a/hgext3rd/topic/flow.py	Sat Dec 09 05:05:39 2017 +0100
+++ b/hgext3rd/topic/flow.py	Sat Dec 09 06:13:28 2017 +0100
@@ -30,6 +30,31 @@
         nodes = [cl.node(r) for r in topublish]
         repo._phasecache.advanceboundary(repo, tr, phases.public, nodes)
 
+def rejectuntopicedchangeset(repo, tr):
+    """Reject the push if there are changeset without topic"""
+    if not tr.changes['revs']: # no new revs
+        return
+
+    mode = repo.ui.config('experimental', 'topic-mode.server', 'ignore')
+
+    revs = list(tr.changes['revs'])
+    untopiced = repo.revs('not public() and (%ld:) - hidden() - topic()', revs)
+    if untopiced:
+        num = len(untopiced)
+        fnode = repo[untopiced.first()].hex()[:10]
+        if num == 1:
+            msg = _("%s") % fnode
+        else:
+            msg = _("%s and %d more") % (fnode, num - 1)
+        if mode == 'warning':
+            fullmsg = _("pushed draft changeset without topic: %s\n")
+            repo.ui.warn(fullmsg % msg)
+        elif mode == 'enforce':
+            fullmsg = _("rejecting draft changesets: %s")
+            raise error.Abort(fullmsg % msg)
+        else:
+            repo.ui.warn(_("unknown 'topic-mode.server': %s\n" % mode))
+
 def wrappush(orig, repo, remote, *args, **kwargs):
     """interpret the --publish flag and pass it to the push operation"""
     newargs = kwargs.copy()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-topic-flow-reject-untopiced.t	Sat Dec 09 06:13:28 2017 +0100
@@ -0,0 +1,171 @@
+Testing the config option for rejecting draft changeset without topic
+The config option is "experimental.topic-mode.server"
+
+  $ . "$TESTDIR/testlib/topic_setup.sh"
+
+Creating a server repo
+
+  $ hg init server
+  $ cd server
+  $ cat <<EOF >>.hg/hgrc
+  > [phases]
+  > publish=False
+  > [experimental]
+  > topic-mode.server = enforce
+  > EOF
+
+  $ hg topic server
+  marked working directory as topic: server
+  $ for ch in a b c; do echo foo > $ch; hg ci -Aqm "Added "$ch; done
+
+  $ hg log -G -T "{rev}:{node|short}\n{desc}  {topics}"
+  @  2:a7b96f87a214
+  |  Added c  server
+  o  1:d6a8197e192a
+  |  Added b  server
+  o  0:49a3f206c9ae
+     Added a  server
+
+  $ cd ..
+
+Creating a client repo
+
+  $ hg clone server client
+  updating to branch default
+  switching to topic server
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd client
+  $ hg log -G -T "{rev}:{node|short}\n{desc}  {topics}"
+  @  2:a7b96f87a214
+  |  Added c  server
+  o  1:d6a8197e192a
+  |  Added b  server
+  o  0:49a3f206c9ae
+     Added a  server
+
+  $ hg topic
+   * server (3 changesets)
+
+Create a changeset without topic
+
+  $ hg topic --clear
+  $ echo foo > d
+  $ hg ci -Aqm "added d"
+
+  $ hg log -G -T "{rev}:{node|short}\n{desc}  {topics}"
+  @  3:4e8b0e0237c6
+  |  added d
+  o  2:a7b96f87a214
+  |  Added c  server
+  o  1:d6a8197e192a
+  |  Added b  server
+  o  0:49a3f206c9ae
+     Added a  server
+
+Push a draft changeset without topic
+
+  $ hg push ../server  --new-branch
+  pushing to ../server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  transaction abort!
+  rollback completed
+  abort: rejecting draft changesets: 4e8b0e0237
+  [255]
+
+  $ hg push ../server -f
+  pushing to ../server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  transaction abort!
+  rollback completed
+  abort: rejecting draft changesets: 4e8b0e0237
+  [255]
+
+Grow the stack with more changesets having topic
+
+  $ hg topic client
+  marked working directory as topic: client
+  $ for ch in e f g; do echo foo > $ch; hg ci -Aqm "Added "$ch; done;
+
+  $ hg log -G -T "{rev}:{node|short}\n{desc}  {topics}"
+  @  6:42c4ac86452a
+  |  Added g  client
+  o  5:3dc456efb491
+  |  Added f  client
+  o  4:18a516babc60
+  |  Added e  client
+  o  3:4e8b0e0237c6
+  |  added d
+  o  2:a7b96f87a214
+  |  Added c  server
+  o  1:d6a8197e192a
+  |  Added b  server
+  o  0:49a3f206c9ae
+     Added a  server
+
+Pushing multiple changeset with some having topics and some not
+
+  $ hg push ../server --new-branch
+  pushing to ../server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 4 changes to 4 files
+  transaction abort!
+  rollback completed
+  abort: rejecting draft changesets: 4e8b0e0237
+  [255]
+
+Testing case when both experimental.topic-mode.server and
+experimental.topic.publish-bare-branch are set
+
+  $ cd ../server
+  $ echo 'topic.publish-bare-branch=True' >> .hg/hgrc
+  $ cd ../client
+  $ hg push ../server --new-branch
+  pushing to ../server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 4 changes to 4 files
+  transaction abort!
+  rollback completed
+  abort: rejecting draft changesets: 4e8b0e0237
+  [255]
+
+Turning the changeset public and testing push
+
+  $ hg phase -r 3 -p
+  $ hg log -G -T "{rev}:{node|short}\n{desc}  {topics}"
+  @  6:42c4ac86452a
+  |  Added g  client
+  o  5:3dc456efb491
+  |  Added f  client
+  o  4:18a516babc60
+  |  Added e  client
+  o  3:4e8b0e0237c6
+  |  added d
+  o  2:a7b96f87a214
+  |  Added c
+  o  1:d6a8197e192a
+  |  Added b
+  o  0:49a3f206c9ae
+     Added a
+
+  $ hg push ../server
+  pushing to ../server
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 4 changes to 4 files
+  active topic 'server' is now empty