Patchwork [1,of,8] namespaces: introduce a generic way to map between names and nodes

login
register
mail settings
Submitter Sean Farley
Date Dec. 15, 2014, 12:37 a.m.
Message ID <eb7489c4b2f83efcfbec.1418603869@laptop.local>
Download mbox | patch
Permalink /patch/7094/
State Accepted
Headers show

Comments

Sean Farley - Dec. 15, 2014, 12:37 a.m.
# HG changeset patch
# User Sean Farley <sean.michael.farley@gmail.com>
# Date 1418588968 28800
#      Sun Dec 14 12:29:28 2014 -0800
# Node ID eb7489c4b2f83efcfbeca4c3b68022bd5596e352
# Parent  495bc1b65d25872324a0220354f048b220304bd1
namespaces: introduce a generic way to map between names and nodes

This patch begins the work to provide a way to register a namespace to handle
'names'. Benefits of this would be,

- improved templating: This would provide {name} which could output any branch,
  bookmark, tag, or any extension registered namespace all without having the
  extension doing any extra work

- improved tab completion: Since this provides a single source of all 'names',
  tab completion would not need to know of each namespace

- changeset lookup: Similar to before, a unified place to get all 'names' will
  allow finding changesets without any extension code having to reimplement
  this

Also, d226fe36e362 has shown us that for internal code which expects a certain
type of method or behavior, we should provide an easy way for extensions to
check this behavior.

Patch

diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py
new file mode 100644
--- /dev/null
+++ b/mercurial/namespaces.py
@@ -0,0 +1,36 @@ 
+from mercurial import util
+
+class namespaces(object):
+    """
+    provides an interface to register a generic many-to-many mapping between
+    some (namespaced) names and nodes. The goal here is to control the
+    pollution of jamming things into tags or bookmarks (in extension-land) and
+    to simplify internal bits of mercurial: log output, tab completion, etc.
+
+    More preciesly, we define a name to node mapping that is surjective (onto)
+    so that we only need three things: a list of names (the domain), a mapping
+    of names to nodes (surjection), and a mapping from nodes to names (since
+    this is not guaranteed to be bijective, we can't simply invert the name
+    mapping).
+
+    We design this name mapping to return a list of nodes. Similarly, this node
+    mapping will return a list of names.
+
+    Furthermore, each name mapping will be passed a name to lookup which might
+    not be in its domain. Therefore, each method must return (and not raise an
+    error) gracefully.
+
+    We'll have a dictionary '_names' where each key is a namespace and
+    its value is a dictionary of:
+      'name' : singular name of the namespace (e.g. "bookmark"
+               vs. "bookmarks")
+      'names': list of all names in the namespace (usually the keys of a
+               dictionary)
+      'namemap': function that inputs a name and returns a list of nodes
+      'nodemap': function that inputs a node and returns a list of names
+    """
+
+    _names_version = 0
+
+    def __init__(self):
+        self._names = util.sortdict()