120 lines
2.9 KiB
Python
120 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2016 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""Functions and classes for formatting buildbot stage annotations."""
|
|
|
|
from __future__ import print_function
|
|
|
|
import abc
|
|
import itertools
|
|
import json
|
|
|
|
import six
|
|
|
|
|
|
class Annotation(object):
|
|
"""Formatted annotation for buildbot."""
|
|
|
|
def __init__(self, name, args):
|
|
"""Initialize instance.
|
|
|
|
Args:
|
|
name: Annotation name.
|
|
args: A sequence of string arguments.
|
|
"""
|
|
self.name = name
|
|
self.args = args
|
|
|
|
def __str__(self):
|
|
inner_text = '@'.join(
|
|
_EscapeArgText(text)
|
|
for text in itertools.chain([self.name], self.args)
|
|
)
|
|
return '@@@%s@@@' % (inner_text,)
|
|
|
|
@property
|
|
def human_friendly(self):
|
|
"""Human-friendly format."""
|
|
if self.args:
|
|
return '%s: %s' % (self.name, '; '.join(self.args))
|
|
else:
|
|
return self.name
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class _NamedAnnotation(Annotation):
|
|
"""Abstract subclass for creating named annotations.
|
|
|
|
Concrete subclasses should define the ANNOTATION_NAME class attribute.
|
|
"""
|
|
|
|
def __init__(self, *args):
|
|
super(_NamedAnnotation, self).__init__(self.ANNOTATION_NAME, args)
|
|
|
|
@abc.abstractproperty
|
|
def ANNOTATION_NAME(self):
|
|
raise NotImplementedError()
|
|
|
|
|
|
class StepLink(_NamedAnnotation):
|
|
"""STEP_LINK annotation."""
|
|
ANNOTATION_NAME = 'STEP_LINK'
|
|
|
|
# Some callers pass in text/url by kwarg. We leave the full signature here
|
|
# so the API is a bit cleaner/more obvious.
|
|
# pylint: disable=useless-super-delegation
|
|
def __init__(self, text, url):
|
|
super(StepLink, self).__init__(text, url)
|
|
|
|
|
|
class StepText(_NamedAnnotation):
|
|
"""STEP_TEXT annotation."""
|
|
ANNOTATION_NAME = 'STEP_TEXT'
|
|
|
|
|
|
class StepWarnings(_NamedAnnotation):
|
|
"""STEP_WARNINGS annotation."""
|
|
ANNOTATION_NAME = 'STEP_WARNINGS'
|
|
|
|
|
|
class StepFailure(_NamedAnnotation):
|
|
"""STEP_FAILURE annotation."""
|
|
ANNOTATION_NAME = 'STEP_FAILURE'
|
|
|
|
|
|
class BuildStep(_NamedAnnotation):
|
|
"""BUILD_STEP annotation."""
|
|
ANNOTATION_NAME = 'BUILD_STEP'
|
|
|
|
|
|
class SetBuildProperty(_NamedAnnotation):
|
|
"""SET_BUILD_PROPERTY annotation."""
|
|
ANNOTATION_NAME = 'SET_BUILD_PROPERTY'
|
|
|
|
def __init__(self, name, value):
|
|
super(SetBuildProperty, self).__init__(name, json.dumps(value))
|
|
|
|
|
|
class SetEmailNotifyProperty(_NamedAnnotation):
|
|
"""SET_BUILD_PROPERTY annotation for email_notify."""
|
|
ANNOTATION_NAME = 'SET_BUILD_PROPERTY'
|
|
|
|
def __init__(self, name, value):
|
|
super(SetEmailNotifyProperty, self).__init__(name, json.dumps(value))
|
|
|
|
def __str__(self):
|
|
inner_text = '@'.join(
|
|
text for text in itertools.chain([self.name], self.args))
|
|
return '@@@%s@@@' % (inner_text)
|
|
|
|
|
|
def _EscapeArgText(text):
|
|
"""Escape annotation argument text.
|
|
|
|
Args:
|
|
text: String to escape.
|
|
"""
|
|
return text.replace('@', '-AT-')
|