mirror of
https://github.com/jongracecox/anybadge.git
synced 2025-07-20 20:01:04 +02:00
Allow badges with no value or no label (#89)
This commit allows badges to be generated with only a label or only a value. Badges must provide at least a label or a value, so it is not valid to create a badge with no label and no value. This will result in a `ValueError` being raised.
This commit is contained in:
committed by
Jon Grace-Cox
parent
a076a4867a
commit
9d4470a1a0
10
README.md
10
README.md
@@ -317,6 +317,16 @@ Here are some examples to show how to use padding to fix layout:
|
||||
|  | `anybadge.Badge("Pipeline status", "😄")` |
|
||||
|  | `anybadge.Badge("Pipeline status", "😄", num_value_padding_chars=1)` |
|
||||
|
||||
### Value or label only
|
||||
|
||||
It is possible to create badges with only a label or only a value. This can be done by passing
|
||||
an empty string to the appropriate field. Note that either a label or value must be provided.
|
||||
|
||||
| Badge | Code |
|
||||
|---------------------------------------------------------------------------------|--------------------------------------|
|
||||
|  | `anybadge.Badge(label="Label only")` |
|
||||
|  | `anybadge.Badge(value="Value only")` |
|
||||
|
||||
### Semantic version support
|
||||
|
||||
Anybadge supports semantic versions for value and threshold keys. This supports color-coded
|
||||
|
@@ -153,6 +153,14 @@ class Badge:
|
||||
self.label = label
|
||||
self.value = value
|
||||
|
||||
if self.label is None:
|
||||
self.label = ""
|
||||
if self.value is None:
|
||||
self.value = ""
|
||||
|
||||
if len(str(self.label)) == 0 and len(str(self.value)) == 0:
|
||||
raise ValueError("Either a label or a value must be provided for a badge.")
|
||||
|
||||
self.value_is_version = semver
|
||||
|
||||
self.value_format = value_format
|
||||
@@ -414,6 +422,9 @@ class Badge:
|
||||
|
||||
Returns: int
|
||||
"""
|
||||
if len(str(self.label)) == 0:
|
||||
return 0
|
||||
|
||||
return int(
|
||||
self.get_text_width(str(self.label))
|
||||
+ (2.0 * self.num_label_padding_chars * self.font_width)
|
||||
@@ -433,6 +444,9 @@ class Badge:
|
||||
|
||||
Returns: int
|
||||
"""
|
||||
if len(str(self.value_text)) == 0:
|
||||
return 0
|
||||
|
||||
return int(
|
||||
self.get_text_width(str(self.value_text))
|
||||
+ (2.0 * self.num_value_padding_chars * self.font_width)
|
||||
|
@@ -52,10 +52,8 @@ examples:
|
||||
"""
|
||||
),
|
||||
)
|
||||
parser.add_argument("-l", "--label", type=str, help="The badge label.")
|
||||
parser.add_argument(
|
||||
"-v", "--value", type=str, help="The badge value.", required=True
|
||||
)
|
||||
parser.add_argument("-l", "--label", type=str, help="The badge label.", default="")
|
||||
parser.add_argument("-v", "--value", type=str, help="The badge value.", default="")
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--value-format",
|
||||
@@ -196,9 +194,6 @@ def main(args=None):
|
||||
if not args.suffix and style.suffix:
|
||||
suffix = style.suffix
|
||||
|
||||
if not label:
|
||||
raise ValueError("Label has not been set. Please use --label argument.")
|
||||
|
||||
# Create threshold list from args
|
||||
threshold_list = [x.split("=") for x in threshold_text]
|
||||
threshold_dict = {x[0]: x[1] for x in threshold_list}
|
||||
|
@@ -24,7 +24,7 @@ def color_examples_table():
|
||||
)
|
||||
|
||||
|
||||
def emoji_examples():
|
||||
def other_examples():
|
||||
"""Generate emoji example badges used in documentation."""
|
||||
examples_dir = Path(__file__).parent / Path("examples")
|
||||
for label, value, file, kwargs in [
|
||||
@@ -38,6 +38,8 @@ def emoji_examples():
|
||||
("Pipeline status", "😟", "pipeline_frown.svg", {"default_color": "Red"}),
|
||||
("🔗", "Documentation", "documentation_link.svg", {}),
|
||||
("🔗", "PyPi", "pypi_link.svg", {}),
|
||||
("", "Value only", "value_only.svg", {}),
|
||||
("Label only", "", "label_only.svg", {}),
|
||||
]:
|
||||
anybadge.Badge(label=label, value=value, **kwargs).write_badge(
|
||||
examples_dir / Path(file), overwrite=True
|
||||
@@ -46,7 +48,7 @@ def emoji_examples():
|
||||
|
||||
def main():
|
||||
color_examples_table()
|
||||
emoji_examples()
|
||||
other_examples()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -34,6 +34,16 @@ anybadge --label="Label" --value="Value" --file "${TEST_FILES}/test_command_line
|
||||
check_rc
|
||||
echo "OK"
|
||||
|
||||
echo -n "Testing with no label..."
|
||||
anybadge --value="Value" --file "${TEST_FILES}/test_command_line_no_label.svg"
|
||||
check_rc
|
||||
echo "OK"
|
||||
|
||||
echo -n "Testing with no value..."
|
||||
anybadge --label="Label" --file "${TEST_FILES}/test_command_line_no_value.svg"
|
||||
check_rc
|
||||
echo "OK"
|
||||
|
||||
echo -n "Testing python -m call... "
|
||||
python -m anybadge --label="Label" --value="Value" --file "${TEST_FILES}/test_m_command_line.svg"
|
||||
check_rc
|
||||
|
23
examples/label_only.svg
Normal file
23
examples/label_only.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="71" height="20">
|
||||
<linearGradient id="b" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<mask id="anybadge_152">
|
||||
<rect width="71" height="20" rx="3" fill="#fff"/>
|
||||
</mask>
|
||||
<g mask="url(#anybadge_152)">
|
||||
<path fill="#555" d="M0 0h71v20H0z"/>
|
||||
<path fill="#4c1" d="M71 0h0v20H71z"/>
|
||||
<path fill="url(#b)" d="M0 0h71v20H0z"/>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="36.5" y="15" fill="#010101" fill-opacity=".3">Label only</text>
|
||||
<text x="35.5" y="14">Label only</text>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="72.0" y="15" fill="#010101" fill-opacity=".3"></text>
|
||||
<text x="71.0" y="14"></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
23
examples/value_only.svg
Normal file
23
examples/value_only.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="71" height="20">
|
||||
<linearGradient id="b" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<mask id="anybadge_151">
|
||||
<rect width="71" height="20" rx="3" fill="#fff"/>
|
||||
</mask>
|
||||
<g mask="url(#anybadge_151)">
|
||||
<path fill="#555" d="M0 0h0v20H0z"/>
|
||||
<path fill="#4c1" d="M0 0h71v20H0z"/>
|
||||
<path fill="url(#b)" d="M0 0h71v20H0z"/>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="1.0" y="15" fill="#010101" fill-opacity=".3"></text>
|
||||
<text x="0.0" y="14"></text>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="36.5" y="15" fill="#010101" fill-opacity=".3">Value only</text>
|
||||
<text x="35.5" y="14">Value only</text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@@ -328,12 +328,6 @@ class TestAnybadge(TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
def test_main_missing_value(self):
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, r"Label has not been set\. Please use --label argument\."
|
||||
):
|
||||
main(["--value", "123", "--file", "test_badge_main.svg", "--overwrite"])
|
||||
|
||||
def test_version_comparison(self):
|
||||
# Define thresholds: <3.0.0=red, <3.2.0=orange <999.0.0=green
|
||||
badge = Badge(
|
||||
@@ -410,3 +404,45 @@ class TestAnybadge(TestCase):
|
||||
output_module = subprocess.check_output(["python", "-m", "anybadge", "--help"])
|
||||
output_script = subprocess.check_output(["anybadge", "--help"])
|
||||
self.assertEqual(output_module, output_script)
|
||||
|
||||
def test_badge_with_no_label(self):
|
||||
"""Test the dimensions for a badge with no label."""
|
||||
badge = Badge(
|
||||
label="",
|
||||
value="Value",
|
||||
)
|
||||
self.assertEqual(
|
||||
badge.label_width,
|
||||
0,
|
||||
"Expected label width to be 0 for badge with no label.",
|
||||
)
|
||||
|
||||
def test_badge_with_no_value(self):
|
||||
"""Test the dimensions for a badge with no value."""
|
||||
badge = Badge(
|
||||
label="Label",
|
||||
value="",
|
||||
)
|
||||
self.assertEqual(
|
||||
badge.value_width,
|
||||
0,
|
||||
"Expected value width to be 0 for badge with no value.",
|
||||
)
|
||||
|
||||
def test_badge_with_no_label_and_no_value(self):
|
||||
"""Test that an exception is raised when trying to create a badge with no label or value."""
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, r"Either a label or a value must be provided for a badge\."
|
||||
):
|
||||
_ = Badge(
|
||||
label="",
|
||||
value="",
|
||||
)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, r"Either a label or a value must be provided for a badge\."
|
||||
):
|
||||
_ = Badge(
|
||||
label=None,
|
||||
value=None,
|
||||
)
|
||||
|
Reference in New Issue
Block a user