Patchwork D1756: remotenames: introduce class to encapsulate remotenames info in an extension

login
register
mail settings
Submitter phabricator
Date Dec. 25, 2017, 8:50 p.m.
Message ID <differential-rev-PHID-DREV-o3o3hkmv6o4iligriv7q-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/26435/
State Superseded
Headers show

Comments

phabricator - Dec. 25, 2017, 8:50 p.m.
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This patch adds a new extension remotenames in which features from hgremotenames
  extension (https://bb/seanfarley/hgremotenames) will be added incrementally.
  This patch introduces a basic class to encapsulate the remotenames information.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1756

AFFECTED FILES
  hgext/remotenames.py
  tests/test-help.t

CHANGE DETAILS




To: pulkit, #hg-reviewers
Cc: mercurial-devel
phabricator - Dec. 25, 2017, 9 p.m.
pulkit added a comment.


  As per previous discussions, the storage part can only go to core directly (https://phab.mercurial-scm.org/D1358#22905). I am not sure about how out of core extension and in-core extension will interact. Also shall I change this extension name to prevent conflict with the out of core one?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1756

To: pulkit, #hg-reviewers
Cc: mercurial-devel
phabricator - Jan. 10, 2018, 11:22 p.m.
durin42 added a comment.


  In https://phab.mercurial-scm.org/D1756#29970, @pulkit wrote:
  
  > As per previous discussions, the storage part can only go to core directly (https://phab.mercurial-scm.org/D1358#22905). I am not sure about how out of core extension and in-core extension will interact. Also shall I change this extension name to prevent conflict with the out of core one?
  
  
  My 2¢: don't worry about the interactions. The existing remotenames is not published on pypi, so it's very unlikely people have it installed and active as just `remotenames=` in their `extensions` block.
  
  No idea if others agree though.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1756

To: pulkit, #hg-reviewers
Cc: durin42, mercurial-devel
phabricator - Jan. 13, 2018, 1 p.m.
pulkit added a comment.


  In https://phab.mercurial-scm.org/D1756#31162, @durin42 wrote:
  
  > In https://phab.mercurial-scm.org/D1756#29970, @pulkit wrote:
  >
  > > As per previous discussions, the storage part can only go to core directly (https://phab.mercurial-scm.org/D1358#22905). I am not sure about how out of core extension and in-core extension will interact. Also shall I change this extension name to prevent conflict with the out of core one?
  >
  >
  > My 2¢: don't worry about the interactions. The existing remotenames is not published on pypi, so it's very unlikely people have it installed and active as just `remotenames=` in their `extensions` block.
  >
  > No idea if others agree though.
  
  
  In that case, I am happy to get this patches reviewed as they are.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1756

To: pulkit, #hg-reviewers
Cc: durin42, mercurial-devel
phabricator - Feb. 14, 2018, 7:05 a.m.
martinvonz added inline comments.

INLINE COMMENTS

> remotenames.py:23
> +
> +class remotenames(dict):
> +    """

Why does this extend dict? Do we expect callers to update bookmarks by doing something like the following? If not, and the extending of dict is just for the convenience of writing the loop in loadnames() below, we should do it differently and not expose the dict-ness to users. For example, this class could have a dict instead of being a dict.

  remotenames = ...
  remotenames['my-bookmark'] = node

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1756

To: pulkit, #hg-reviewers, durin42
Cc: martinvonz, durin42, mercurial-devel
Sean Farley - Feb. 20, 2018, 10:37 p.m.
martinvonz (Martin von Zweigbergk) <phabricator@mercurial-scm.org> writes:

> martinvonz added inline comments.
>
> INLINE COMMENTS
>
>> remotenames.py:23
>> +
>> +class remotenames(dict):
>> +    """
>
> Why does this extend dict? Do we expect callers to update bookmarks by doing something like the following? If not, and the extending of dict is just for the convenience of writing the loop in loadnames() below, we should do it differently and not expose the dict-ness to users. For example, this class could have a dict instead of being a dict.
>
>   remotenames = ...
>   remotenames['my-bookmark'] = node

When I wrote this, updating the bookmark (IIRC) was done through a
dict-like interface. Or perhaps I wanted it to be that way so that's how
I wrote it here.

Patch

diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -273,6 +273,7 @@ 
        purge         command to delete untracked files from the working
                      directory
        relink        recreates hardlinks between repository clones
+       remotenames   showing remotebookmarks and remotebranches in UI
        schemes       extend schemes with shortcuts to repository swarms
        share         share a common history between several working directories
        shelve        save and restore changes to the working directory
diff --git a/hgext/remotenames.py b/hgext/remotenames.py
new file mode 100644
--- /dev/null
+++ b/hgext/remotenames.py
@@ -0,0 +1,77 @@ 
+# remotenames.py - extension to display remotenames
+#
+# Copyright 2017 Augie Fackler <raf@durin42.com>
+# Copyright 2017 Sean Farley <sean@farley.io>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+""" showing remotebookmarks and remotebranches in UI """
+
+from __future__ import absolute_import
+
+from mercurial import (
+    logexchange,
+)
+
+# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
+# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
+# be specifying the version(s) of Mercurial they are tested with, or
+# leave the attribute unspecified.
+testedwith = 'ships-with-hg-core'
+
+class remotenames(dict):
+    """
+    This class encapsulates all the remotenames state. It also contains
+    methods to access that state in convenient ways.
+    """
+
+    def __init__(self, repo, *args):
+        dict.__init__(self, *args)
+        self._repo = repo
+        self['bookmarks'] = {}
+        self['branches'] = {}
+        self.loadnames()
+        self._loadednames = True
+
+    def loadnames(self):
+        """ loads the remotenames information from the remotenames file """
+        for rtype in ('bookmarks', 'branches'):
+            for node, rpath, name in logexchange.readremotenamefile(repo,
+                                                                    rtype):
+                rname = rpath + '/' + name
+                self[rtype][rname] = [node]
+
+    def clearnames(self):
+        """ Clear all remote names state """
+        self['bookmarks'] = {}
+        self['branches'] = {}
+        self._invalidatecache()
+        self._loadednames = False
+
+    def _invalidatecache(self):
+        self._nodetobmarks = None
+        self._nodetobranch = None
+
+    def bmarktonodes(self):
+        return self['bookmarks']
+
+    def nodetobmarks(self):
+        if not self._nodetobmarks:
+            bmarktonodes = self.bmarktonodes()
+            self._nodetobmarks = {}
+            for name, node in bmarktonodes.iteritems():
+                self._nodetobmarks.setdefault(node[0], []).append(name)
+        return self._nodetobmarks
+
+    def branchtonodes(self):
+        return self['branches']
+
+    def nodetobranch(self):
+        if not self._nodetobranch:
+            branchtonodes = self.branchtonodes()
+            self._nodetobranch = {}
+            for name, nodes in branchtonodes.iteritems():
+                for node in nodes:
+                    self._nodetobranch[node] = [name]
+        return self._nodetobranch