diff --git a/README.md b/README.md
index 21218ae..fcf9e18 100644
--- a/README.md
+++ b/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
diff --git a/anybadge/badge.py b/anybadge/badge.py
index a8b6b54..d21e1df 100644
--- a/anybadge/badge.py
+++ b/anybadge/badge.py
@@ -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)
diff --git a/anybadge/cli.py b/anybadge/cli.py
index b46e925..1f76bd2 100644
--- a/anybadge/cli.py
+++ b/anybadge/cli.py
@@ -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}
diff --git a/build_examples.py b/build_examples.py
index e39b531..1eb5259 100644
--- a/build_examples.py
+++ b/build_examples.py
@@ -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__":
diff --git a/docker/test/shell_tests.sh b/docker/test/shell_tests.sh
index aa2e736..ed055f6 100755
--- a/docker/test/shell_tests.sh
+++ b/docker/test/shell_tests.sh
@@ -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
diff --git a/examples/label_only.svg b/examples/label_only.svg
new file mode 100644
index 0000000..27372bb
--- /dev/null
+++ b/examples/label_only.svg
@@ -0,0 +1,23 @@
+
+
diff --git a/examples/value_only.svg b/examples/value_only.svg
new file mode 100644
index 0000000..7e79946
--- /dev/null
+++ b/examples/value_only.svg
@@ -0,0 +1,23 @@
+
+
diff --git a/tests/test_anybadge.py b/tests/test_anybadge.py
index c5c369a..47ad8f9 100644
--- a/tests/test_anybadge.py
+++ b/tests/test_anybadge.py
@@ -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,
+ )