diff --git a/README.md b/README.md
index c91830c..76bb923 100644
--- a/README.md
+++ b/README.md
@@ -178,9 +178,9 @@ badges based on version numbering. Here are some examples:
```python
badge = Badge(
- label='Version',
- value='3.0.0',
- thresholds={'3.0.0': 'red', '3.2.0': 'orange', '999.0.0': 'green'},
+ label='Version',
+ value='3.0.0',
+ thresholds={'3.0.0': 'red', '3.2.0': 'orange', '999.0.0': 'green'},
semver=True
)
```
@@ -192,7 +192,7 @@ In the above example the thresholds equate to the following:
* If value is < 999.0.0 then badge will be green.
Each threshold entry is used to define the upper bounds of the threshold. If you don't know the
-upper bound for your version number threshold you will need to provide an extreme upper bound -
+upper bound for your version number threshold you will need to provide an extreme upper bound -
in this example it is `999.0.0`.
### Examples
@@ -201,37 +201,66 @@ in this example it is `999.0.0`.
```bash
anybadge --value=2.22 --file=pylint.svg pylint
```
-
+
#### Pylint using arguments
```bash
anybadge -l pylint -v 2.22 -f pylint.svg 2=red 4=orange 8=yellow 10=green
```
-
+
#### Coverage using template
```bash
anybadge --value=65 --file=coverage.svg coverage
-```
-
+```
+
#### Pipeline, using labeled colors
```bash
anybadge --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
```
-
+
#### Badge with fixed color
```bash
-anybadge --label=awesomeness --value="110%" --file=awesomeness.svg --color=#97CA00
+anybadge --label=awesomeness --value="110%" --file=awesomeness.svg --color='#97CA00'
```
-
+
+
+#### GitLab Scoped style badge
+```bash
+anybadge --style=gitlab-scoped --label=Project --value=Archimedes --file=gitlab_scoped.svg --color='#c1115d'
+```
+
#### Thresholds based on semantic versions
```bash
anybadge --label=Version --value=2.4.5 --file=version.svg 1.0.0=red 2.4.6=orange 2.9.1=yellow 999.0.0=green
```
+#### Importing in your own app
+```python
+from anybadge import Badge
+
+test1 = Badge(
+ label,
+ value,
+ font_name='DejaVu Sans,Verdana,Geneva,sans-serif',
+ font_size=11,
+ num_padding_chars=0.5,
+ template='\n',
+ value_prefix='',
+ value_suffix='',
+ thresholds=None,
+ default_color='#4c1',
+ use_max_when_value_exceeds=True,
+ value_format=None,
+ text_color='#fff'
+)
+
+test1.write_badge('test1.svg')
+```
+
### Options
These are the command line options:
@@ -273,6 +302,10 @@ optional arguments:
Font size.
-t TEMPLATE, --template TEMPLATE
Location of alternative template .svg file.
+ -s STYLE, --style STYLE
+ Alternative style of badge to create. Valid values are
+ "gitlab-scoped", "default". This overrides any templates
+ passed using --template.
-u, --use-max Use the maximum threshold color when the value exceeds
the maximum threshold.
-f FILE, --file FILE Output file location.
@@ -281,6 +314,8 @@ optional arguments:
Text color. Single value affects both labeland value
colors. A comma separated pair affects label and value
text respectively.
+```
+
Examples
--------
@@ -289,22 +324,29 @@ thresholds.
Pylint::
+```
anybadge.py --value=2.22 --file=pylint.svg pylint
anybadge.py --label=pylint --value=2.22 --file=pylint.svg 2=red 4=orange 8=yellow 10=green
+```
Coverage::
+```
anybadge.py --value=65 --file=coverage.svg coverage
anybadge.py --label=coverage --value=65 --suffix='%%' --file=coverage.svg 50=red 60=orange 80=yellow 100=green
+```
CI Pipeline::
+```
anybadge.py --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
+```
Python usage
============
Here is the output of ``help(anybadge)``::
+```
Help on module anybadge:
NAME
@@ -317,30 +359,56 @@ DESCRIPTION
CLASSES
builtins.object
Badge
-
+
class Badge(builtins.object)
- | Badge(label, value, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11, num_padding_chars=0.5, template='\n', value_prefix='', value_suffix='', thresholds=None, default_color='#4c1', use_max_when_value_exceeds=True, value_format=None, text_color='#fff')
- |
+ | Badge(label, value, font_name=None, font_size=None, num_padding_chars=None, num_label_padding_chars=None, num_value_padding_chars=None, template=None, style=None, value_prefix='', value_suffix='', thresholds=None, default_color=None, use_max_when_value_exceeds=True, value_format=None, text_color=None, semver=False)
+ |
| Badge class used to generate badges.
- |
+ |
+ | Args:
+ | label(str): Badge label text.
+ | value(str): Badge value text.
+ | font_name(str, optional): Name of font to use.
+ | font_size(int, optional): Font size.
+ | num_padding_chars(float, optional): Number of padding characters to use to give extra
+ | space around text.
+ | num_label_padding_chars(float, optional): Number of padding characters to use to give extra
+ | space around label text.
+ | num_value_padding_chars(float, optional): Number of padding characters to use to give extra
+ | space around value text.
+ | template(str, optional): String containing the SVG template. This should be valid SVG
+ | file content with place holders for variables to be populated during rendering.
+ | style(str, optional): Style of badge to create. This will make anybadge render a badge in a
+ | different style. Valid values are "gitlab-scoped", "default". Default is "default".
+ | value_prefix(str, optional): Prefix to be placed before value.
+ | value_suffix(str, optional): Suffix to be placed after value.
+ | thresholds(dict, optional): A dictionary containing thresholds used to select badge
+ | color based on the badge value.
+ | default_color(str, optional): Badge color as a name or as an HTML color code.
+ | use_max_when_value_exceeds(bool, optional): Choose whether to use the maximum threshold
+ | value when the badge value exceeds the top threshold. Default is True.
+ | value_format(str, optional) String with formatting to be used to format the value text.
+ | text_color(str, optional): Text color as a name or as an HTML color code.
+ | semver(bool, optional): Used to indicate that the value is a semantic version number.
+ |
| Examples:
- |
+ |
| Create a simple green badge:
- |
+ |
| >>> badge = Badge('label', 123, default_color='green')
- |
+ |
| Write a badge to file, overwriting any existing file:
- |
+ |
| >>> badge = Badge('label', 123, default_color='green')
| >>> badge.write_badge('demo.svg', overwrite=True)
- |
+ |
| Here are a number of examples showing thresholds, since there
| are certain situations that may not be obvious:
- |
+ |
| >>> badge = Badge('pipeline', 'passing', thresholds={'passing': 'green', 'failing': 'red'})
| >>> badge.badge_color
| 'green'
- |
+ |
| 2.32 is not <2
| 2.32 is < 4, so 2.32 yields orange
| >>> badge = Badge('pylint', 2.32, thresholds={2: 'red',
@@ -349,7 +417,7 @@ CLASSES
| ... 10: 'green'})
| >>> badge.badge_color
| 'orange'
- |
+ |
| 8 is not <8
| 8 is <4, so 8 yields orange
| >>> badge = Badge('pylint', 8, thresholds={2: 'red',
@@ -358,7 +426,7 @@ CLASSES
| ... 10: 'green'})
| >>> badge.badge_color
| 'green'
- |
+ |
| 10 is not <8, but use_max_when_value_exceeds defaults to
| True, so 10 yields green
| >>> badge = Badge('pylint', 11, thresholds={2: 'red',
@@ -367,7 +435,7 @@ CLASSES
| ... 10: 'green'})
| >>> badge.badge_color
| 'green'
- |
+ |
| 11 is not <10, and use_max_when_value_exceeds is set to
| False, so 11 yields the default color '#4c1'
| >>> badge = Badge('pylint', 11, use_max_when_value_exceeds=False,
@@ -375,149 +443,229 @@ CLASSES
| ... 10: 'green'})
| >>> badge.badge_color
| '#4c1'
- |
+ |
| Methods defined here:
- |
- | __init__(self, label, value, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11, num_padding_chars=0.5, template='\n', value_prefix='', value_suffix='', thresholds=None, default_color='#4c1', use_max_when_value_exceeds=True, value_format=None, text_color='#fff')
+ |
+ | __init__(self, label, value, font_name=None, font_size=None, num_padding_chars=None, num_label_padding_chars=None, num_value_padding_chars=None, template=None, style=None, value_prefix='', value_suffix='', thresholds=None, default_color=None, use_max_when_value_exceeds=True, value_format=None, text_color=None, semver=False)
| Constructor for Badge class.
- |
+ |
+ | __repr__(self)
+ | Return a representation of the Badge object instance.
+ |
+ | The output of the __repr__ function could be used to recreate the current object.
+ |
+ | Examples:
+ |
+ | >>> badge = Badge('example', '123.456')
+ | >>> repr(badge)
+ | "Badge('example', '123.456')"
+ |
+ | >>> badge = Badge('example', '123.456', value_suffix='TB')
+ | >>> repr(badge)
+ | "Badge('example', '123.456', value_suffix='TB')"
+ |
+ | >>> badge = Badge('example', '123.456', text_color='#111111', value_suffix='TB')
+ | >>> repr(badge)
+ | "Badge('example', '123.456', value_suffix='TB', text_color='#111111')"
+ |
+ | >>> badge = Badge('example', '123', num_padding_chars=5)
+ | >>> repr(badge)
+ | "Badge('example', '123', num_padding_chars=5)"
+ |
+ | >>> badge = Badge('example', '123', num_label_padding_chars=5)
+ | >>> repr(badge)
+ | "Badge('example', '123', num_label_padding_chars=5)"
+ |
+ | >>> badge = Badge('example', '123', num_label_padding_chars=5, num_value_padding_chars=6,
+ | ... template='template.svg', value_prefix='$', thresholds={10: 'green', 30: 'red'},
+ | ... default_color='red', use_max_when_value_exceeds=False, value_format="%s m/s")
+ | >>> repr(badge)
+ | "Badge('example', '123', num_label_padding_chars=5, num_value_padding_chars=6, template='template.svg', value_prefix='$', thresholds={10: 'green', 30: 'red'}, default_color='red', use_max_when_value_exceeds=False, value_format='%s m/s')"
+ |
+ | __str__(self)
+ | Return string representation of badge.
+ |
+ | This will return the badge SVG text.
+ |
+ | Returns: str
+ |
+ | Examples:
+ |
+ | >>> print(Badge('example', '123')) # doctest: +ELLIPSIS
+ |
+ | ...
+ |
| get_text_width(self, text)
| Return the width of text.
- |
+ |
| Args:
| text(str): Text to get the pixel width of.
- |
+ |
| Returns:
| int: Pixel width of the given text based on the badges selected font.
- |
+ |
| This implementation assumes a fixed font of:
- |
+ |
| font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"
| >>> badge = Badge('x', 1, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11)
| >>> badge.get_text_width('pylint')
| 34
- |
+ |
| write_badge(self, file_path, overwrite=False)
| Write badge to file.
- |
+ |
| ----------------------------------------------------------------------
- | Data descriptors defined here:
- |
- | __dict__
- | dictionary for instance variables (if defined)
- |
- | __weakref__
- | list of weak references to the object (if defined)
- |
+ | Readonly properties defined here:
+ |
+ | arc_start
+ | The position where the arc on the gitlab-scoped should start.
+ |
+ | Returns: int
+ |
+ | Examples:
+ |
+ | >>> badge = Badge('pylint', '5')
+ | >>> badge.arc_start
+ | 58
+ |
| badge_color
| Badge color based on the configured thresholds.
- |
+ |
| Returns: str
- |
+ |
| badge_color_code
| Return the color code for the badge.
- |
+ |
| Returns: str
- |
+ |
+ | Raises: ValueError when an invalid badge color is set.
+ |
| badge_svg_text
| The badge SVG text.
- |
+ |
| Returns: str
- |
+ |
| badge_width
| The total width of badge.
- |
+ |
| Returns: int
- |
+ |
| Examples:
- |
+ |
| >>> badge = Badge('pylint', '5')
| >>> badge.badge_width
- | 103
- |
+ | 61
+ |
| color_split_position
| The SVG x position where the color split should occur.
- |
+ |
| Returns: int
- |
+ |
+ | float_thresholds
+ | Thresholds as a dict using floats as keys.
+ |
| font_width
| Return the width multiplier for a font.
- |
+ |
| Returns:
| int: Maximum pixel width of badges selected font.
- |
+ |
| Example:
- |
+ |
| >>> Badge(label='x', value='1').font_width
| 10
- |
+ |
| label_anchor
| The SVG x position of the middle anchor for the label text.
- |
+ |
| Returns: float
- |
+ |
| label_anchor_shadow
| The SVG x position of the label shadow anchor.
- |
+ |
| Returns: float
- |
+ |
| label_width
| The SVG width of the label text.
- |
+ |
| Returns: int
- |
+ |
+ | semver_thresholds
+ | Thresholds as a dict using LooseVersion as keys.
+ |
+ | semver_version
+ | The semantic version represented by the value string.
+ |
+ | Returns: LooseVersion
+ |
| value_anchor
| The SVG x position of the middle anchor for the value text.
- |
+ |
| Returns: float
- |
+ |
| value_anchor_shadow
| The SVG x position of the value shadow anchor.
- |
+ |
| Returns: float
- |
+ |
+ | value_box_width
+ | The SVG width of the value text box.
+ |
+ | Returns: int
+ |
| value_is_float
| Identify whether the value text is a float.
- |
+ |
| Returns: bool
- |
+ |
| value_is_int
| Identify whether the value text is an int.
- |
+ |
| Returns: bool
- |
+ |
| value_type
| The Python type associated with the value.
- |
+ |
| Returns: type
- |
+ |
| value_width
| The SVG width of the value text.
- |
+ |
| Returns: int
+ |
+ | ----------------------------------------------------------------------
+ | Data descriptors defined here:
+ |
+ | __dict__
+ | dictionary for instance variables (if defined)
+ |
+ | __weakref__
+ | list of weak references to the object (if defined)
FUNCTIONS
- main()
+ main(args=None)
Generate a badge based on command line arguments.
-
- parse_args()
+
+ parse_args(args)
Parse the command line arguments.
DATA
BADGE_TEMPLATES = {'coverage': {'label': 'coverage', 'suffix': '%', 't...
- COLORS = {'green': '#4c1', 'lightgrey': '#9f9f9f', 'orange': '#fe7d37'...
+ COLORS = {'aqua': '#00FFFF', 'black': '#000000', 'blue': '#0000FF', 'b...
DEFAULT_COLOR = '#4c1'
DEFAULT_FONT = 'DejaVu Sans,Verdana,Geneva,sans-serif'
DEFAULT_FONT_SIZE = 11
DEFAULT_TEXT_COLOR = '#fff'
- FONT_WIDTHS = {'DejaVu Sans,Verdana,Geneva,sans-serif': {11: 10}}
+ FONT_WIDTHS = {'Arial, Helvetica, sans-serif': {11: 8}, 'DejaVu Sans,V...
+ MASK_ID_PREFIX = 'anybadge_'
NUM_PADDING_CHARS = 0.5
+ TEMPLATE_GITLAB_SCOPED_SVG = '\n...
TEMPLATE_SVG = '\n"""
+# Template SVG for GitLab Scoped label and value badges with placeholders for
+# various items that will be added during final creation.
+TEMPLATE_GITLAB_SCOPED_SVG = """
+"""
+
# Define some templates that can be used for common badge types, saving
# from having to provide thresholds and labels each time.
BADGE_TEMPLATES = {
@@ -133,6 +158,8 @@ class Badge(object):
space around value text.
template(str, optional): String containing the SVG template. This should be valid SVG
file content with place holders for variables to be populated during rendering.
+ style(str, optional): Style of badge to create. This will make anybadge render a badge in a
+ different style. Valid values are "gitlab-scoped", "default". Default is "default".
value_prefix(str, optional): Prefix to be placed before value.
value_suffix(str, optional): Suffix to be placed after value.
thresholds(dict, optional): A dictionary containing thresholds used to select badge
@@ -200,7 +227,7 @@ class Badge(object):
def __init__(self, label, value, font_name=None, font_size=None,
num_padding_chars=None, num_label_padding_chars=None,
- num_value_padding_chars=None, template=None,
+ num_value_padding_chars=None, template=None, style=None,
value_prefix='', value_suffix='', thresholds=None, default_color=None,
use_max_when_value_exceeds=True, value_format=None, text_color=None,
semver=False):
@@ -222,6 +249,8 @@ class Badge(object):
num_value_padding_chars = num_padding_chars
if not template:
template = TEMPLATE_SVG
+ if style not in ['gitlab-scoped']:
+ style = "default"
if not default_color:
default_color = DEFAULT_COLOR
if not text_color:
@@ -250,6 +279,7 @@ class Badge(object):
self.num_label_padding_chars = num_label_padding_chars
self.num_value_padding_chars = num_value_padding_chars
self.template = template
+ self.style = style
self.thresholds = thresholds
self.default_color = default_color
@@ -313,6 +343,8 @@ class Badge(object):
optional_args += ", num_value_padding_chars=%s" % repr(self.num_value_padding_chars)
if self.template != TEMPLATE_SVG:
optional_args += ", template=%s" % repr(self.template)
+ if self.style != 'default':
+ optional_args += ", style=%s" % repr(self.style)
if self.value_prefix != '':
optional_args += ", value_prefix=%s" % repr(self.value_prefix)
if self.value_suffix != '':
@@ -337,13 +369,13 @@ class Badge(object):
def _repr_svg_(self):
"""Return SVG representation when used inside Jupyter notebook cells.
-
+
This will render the SVG immediately inside a notebook cell when creating
a Badge instance without assigning it to an identifier.
"""
return self.badge_svg_text
-
-
+
+
@classmethod
def _get_next_mask_id(cls):
"""Return a new mask ID from a singleton sequence maintained on the class.
@@ -357,6 +389,22 @@ class Badge(object):
return MASK_ID_PREFIX + str(cls.mask_id)
+ def _get_svg_template(self):
+ """Return the correct SVG template to render, based on the style and template
+ that have been set
+
+ Returns: str
+ """
+ if self.style == "gitlab-scoped":
+ return TEMPLATE_GITLAB_SCOPED_SVG
+
+ # Identify whether template is a file or the actual template text
+ if len(self.template.split('\n')) == 1:
+ with open(self.template, mode='r') as file_handle:
+ return file_handle.read()
+ else:
+ return self.template
+
@property
def semver_version(self):
"""The semantic version represented by the value string.
@@ -443,6 +491,14 @@ class Badge(object):
"""
return int(self.get_text_width(str(self.value_text)) + (2.0 * self.num_value_padding_chars * self.font_width))
+ @property
+ def value_box_width(self):
+ """The SVG width of the value text box.
+
+ Returns: int
+ """
+ return self.value_width - 9
+
@property
def font_width(self):
"""Return the width multiplier for a font.
@@ -511,6 +567,20 @@ class Badge(object):
"""
return self.label_width + self.value_width
+ @property
+ def arc_start(self):
+ """The position where the arc on the gitlab-scoped should start.
+
+ Returns: int
+
+ Examples:
+
+ >>> badge = Badge('pylint', '5')
+ >>> badge.arc_start
+ 51
+ """
+ return self.badge_width - 10
+
@property
def badge_svg_text(self):
"""The badge SVG text.
@@ -518,12 +588,7 @@ class Badge(object):
Returns: str
"""
- # Identify whether template is a file or the actual template text
- if len(self.template.split('\n')) == 1:
- with open(self.template, mode='r') as file_handle:
- badge_text = file_handle.read()
- else:
- badge_text = self.template
+ badge_text = self._get_svg_template()
return badge_text.replace('{{ badge width }}', str(self.badge_width)) \
.replace('{{ font name }}', self.font_name) \
@@ -538,8 +603,10 @@ class Badge(object):
.replace('{{ label text color }}', self.label_text_color) \
.replace('{{ value text color }}', self.value_text_color) \
.replace('{{ color split x }}', str(self.color_split_position)) \
- .replace('{{ value width }}', str(self.value_width))\
- .replace('{{ mask id }}', self.mask_id)
+ .replace('{{ value width }}', str(self.value_width)) \
+ .replace('{{ mask id }}', self.mask_id) \
+ .replace('{{ value box width }}', str(self.value_box_width)) \
+ .replace('{{ arc start }}', str(self.arc_start))
def __str__(self):
"""Return string representation of badge.
@@ -824,6 +891,9 @@ examples:
parser.add_argument('-t', '--template', type=str, help='Location of alternative '
'template .svg file.',
default=TEMPLATE_SVG)
+ parser.add_argument('-st', '--style', type=str, help='Alternative style of badge to create. Valid '
+ 'values are "gitlab-scoped", "default". This '
+ 'overrides any templates passed using --template.')
parser.add_argument('-u', '--use-max', action='store_true',
help='Use the maximum threshold color when the value exceeds the '
'maximum threshold.')
@@ -878,7 +948,7 @@ def main(args=None):
badge = Badge(label, args.value, value_prefix=args.prefix, value_suffix=suffix,
default_color=args.color, num_padding_chars=args.padding,
num_label_padding_chars=args.label_padding, num_value_padding_chars=args.value_padding,
- font_name=args.font, font_size=args.font_size, template=args.template,
+ font_name=args.font, font_size=args.font_size, template=args.template, style=args.style,
use_max_when_value_exceeds=args.use_max, thresholds=threshold_dict,
value_format=args.value_format, text_color=args.text_color, semver=args.semver)
diff --git a/examples/gitlab_scoped.svg b/examples/gitlab_scoped.svg
new file mode 100644
index 0000000..b4835ec
--- /dev/null
+++ b/examples/gitlab_scoped.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file