Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Unified Diff: recipe_engine/third_party/client-py/libs/logdog/streamname.py

Issue 2265673002: Add LogDog / annotation protobuf support. (Closed) Base URL: https://github.com/luci/recipes-py@step-formal-struct
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: recipe_engine/third_party/client-py/libs/logdog/streamname.py
diff --git a/recipe_engine/third_party/client-py/libs/logdog/streamname.py b/recipe_engine/third_party/client-py/libs/logdog/streamname.py
index 3b92fa72980a69d9ec3180c1e257c1ffe895d20b..8aaffb830b84db23fd0fdc31f93bec56ee7087cf 100644
--- a/recipe_engine/third_party/client-py/libs/logdog/streamname.py
+++ b/recipe_engine/third_party/client-py/libs/logdog/streamname.py
@@ -3,8 +3,10 @@
# that can be found in the LICENSE file.
import re
+import string
import types
+_ALNUM_CHARS = string.ascii_letters + string.digits
_SEGMENT_RE_BASE = r'[a-zA-Z0-9][a-zA-Z0-9:_\-.]*'
_STREAM_NAME_RE = re.compile('^(' + _SEGMENT_RE_BASE + ')(/' +
_SEGMENT_RE_BASE + ')*$')
@@ -13,6 +15,7 @@ _MAX_STREAM_NAME_LENGTH = 4096
_MAX_TAG_KEY_LENGTH = 64
_MAX_TAG_VALUE_LENGTH = 4096
+
def validate_stream_name(v, maxlen=None):
"""Verifies that a given stream name is valid.
@@ -42,3 +45,63 @@ def validate_tag(key, value):
"""
validate_stream_name(key, maxlen=_MAX_TAG_KEY_LENGTH)
validate_stream_name(value, maxlen=_MAX_TAG_VALUE_LENGTH)
+
+
+def normalize(v, prefix=None):
+ """Given a string, "v", mutate it into a valid stream name.
+
+ This operates by replacing invalid stream naem characters with underscores (_)
+ when encountered.
+
+ A special case is when "v" begins with an invalid character. In this case, we
+ will replace it with the "prefix", if one is supplied.
+
+ See _STREAM_NAME_RE for a description of a valid stream name.
+
+ Raises:
+ ValueError: If normalization could not be successfully performed.
+ """
+ if len(v) == 0:
+ if not prefix:
+ raise ValueError('Cannot normalize empty name with no prefix.')
+ v = prefix
+ else:
+ out = []
+ for i, ch in enumerate(v):
+ if i == 0 and not _is_valid_stream_char(ch, first=True):
+ # The first letter is special, and must be alphanumeric.
+ # If we have a prefix, prepend that to the resulting string.
+ if prefix is None:
+ raise ValueError('Name has invalid beginning, and no prefix was '
+ 'provided.')
+ out.append(prefix)
+
+ if not _is_valid_stream_char(ch):
+ ch = '_'
+ out.append(ch)
+ v = ''.join(out)
+
+ # Validate the resulting string.
+ validate_stream_name(v)
+ return v
+
+
+def _is_valid_stream_char(ch, first=False):
+ """Returns (bool): True if a character is alphanumeric.
+
+ The first character must be alphanumeric, matching [a-zA-Z0-9].
+ Additional characters must either be alphanumeric or one of: (: _ - .).
+
+ Args:
+ ch (str): the character to evaluate.
+ first (bool): if true, apply special first-character constraints.
+ """
+ # Alphanumeric check.
+ if ch in _ALNUM_CHARS:
+ return True
+ if first:
+ # The first character must be alphanumeric.
+ return False
+
+ # Check additional middle-name characters:
+ return ch in ':_-./'

Powered by Google App Engine
This is Rietveld 408576698