diff mercurial/wireprotov2server.py @ 39813:c30faea8d02d

wireprotov2: advertise set of valid values for requestable fields changesetdata, manifestdata, and filedata all allow the caller to specify what data fields to request. Data fields are extensible and may evolve over time. In order to prevent clients from making requests for fields that are not available, the client needs to know what fields are available. This commit teaches the server to declare a set of "valid values" for wire protocol command arguments. That set of values is exposed in the command's capabilities descriptor. The changesetdata, manifestdata, and filedata commands all declare their set of available "fields." Differential Revision: https://phab.mercurial-scm.org/D4619
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 17 Sep 2018 11:54:00 -0700
parents 8e7e822e85ec
children d059cb669632
line wrap: on
line diff
--- a/mercurial/wireprotov2server.py	Mon Sep 17 10:15:27 2018 -0700
+++ b/mercurial/wireprotov2server.py	Mon Sep 17 11:54:00 2018 -0700
@@ -433,8 +433,6 @@
         'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
     }
 
-    # TODO expose available changesetdata fields.
-
     for command, entry in COMMANDS.items():
         args = {}
 
@@ -449,6 +447,9 @@
             if not meta['required']:
                 args[arg][b'default'] = meta['default']()
 
+            if meta['validvalues']:
+                args[arg][b'validvalues'] = meta['validvalues']
+
         caps['commands'][command] = {
             'args': args,
             'permissions': [entry.permission],
@@ -563,6 +564,9 @@
        ``example``
           An example value for this argument.
 
+       ``validvalues``
+          Set of recognized values for this argument.
+
     ``permission`` defines the permission type needed to run this command.
     Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
     respectively. Default is to assume command requires ``push`` permissions
@@ -619,6 +623,7 @@
 
         meta.setdefault('default', lambda: None)
         meta.setdefault('required', False)
+        meta.setdefault('validvalues', None)
 
     def register(func):
         if name in COMMANDS:
@@ -656,11 +661,13 @@
             'type': 'set',
             'default': set,
             'example': {b'parents', b'revision'},
+            'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
         },
     },
     permission='pull')
 def changesetdata(repo, proto, noderange, nodes, fields):
     # TODO look for unknown fields and abort when they can't be serviced.
+    # This could probably be validated by dispatcher using validvalues.
 
     if noderange is None and nodes is None:
         raise error.WireprotoCommandError(
@@ -808,6 +815,7 @@
             'type': 'set',
             'default': set,
             'example': {b'parents', b'revision'},
+            'validvalues': {b'parents', b'revision'},
         },
         'path': {
             'type': 'bytes',
@@ -966,6 +974,7 @@
             'type': 'set',
             'default': set,
             'example': {b'parents', b'revision'},
+            'validvalues': {b'parents', b'revision'},
         },
         'tree': {
             'type': 'bytes',