Skip to content

Commit 3df41bc

Browse files
committed
Fix #208: Introduce VersionInfo.isvalid() function
* VersionInfo.isvalid(cls, version:str) -> bool * Add test case * Describe function in documentation * Amend pysemver script with "is-valid" subcommand * Update manpage (pysemver.rst) * Update `CHANGELOG.rst`
1 parent 445f47a commit 3df41bc

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Features
2020
* :gh:`191` (:pr:`194`): Created manpage for pysemver
2121
* :gh:`196` (:pr:`197`): Added distribution specific installation instructions
2222
* :gh:`201` (:pr:`202`): Reformatted source code with black
23+
* :gh:`208` (:pr:`209`): Introduce new function :func:`semver.VersionInfo.isvalid`
24+
and extend :command:`pysemver` with :command:`is-valid` subcommand
25+
2326

2427
Bug Fixes
2528
---------
@@ -54,7 +57,6 @@ Features
5457
* :pr:`166`: Reworked :file:`.gitignore` file
5558
* :gh:`167` (:pr:`168`): Introduced global constant :data:`SEMVER_SPEC_VERSION`
5659

57-
5860
Bug Fixes
5961
---------
6062

docs/pysemver.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,28 @@ are valid (return code 0) or not (return code != 0)::
121121
ERROR 1.2.x is not valid SemVer string
122122
2
123123

124+
pysemver is-valid
125+
~~~~~~~~~~~~~~~~~
126+
127+
Checks if a string is a valid semver version.
128+
129+
.. code:: bash
130+
131+
pysemver is-valid <VERSION>
132+
133+
.. option:: <VERSION>
134+
135+
The version string to check.
136+
137+
The *error code* returned by the script indicates if the
138+
version is valid (=0) or not (!=0)::
139+
140+
$ pysemver is-valid 1.2.3; echo $?
141+
0
142+
$ pysemver is-valid 2.1; echo $?
143+
ERROR Invalid version '2.1'
144+
2
145+
124146

125147
See also
126148
--------

docs/usage.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ A version can be created in different ways:
5353
>>> semver.VersionInfo(1, 2, 3, 4, 5)
5454
VersionInfo(major=1, minor=2, patch=3, prerelease=4, build=5)
5555

56+
If you pass an invalid version string you will get a ``ValueError``::
57+
58+
>>> semver.parse("1.2")
59+
Traceback (most recent call last)
60+
...
61+
ValueError: 1.2 is not valid SemVer string
62+
5663

5764
Parsing a Version String
5865
------------------------
@@ -77,6 +84,20 @@ Parsing a Version String
7784
{'major': 3, 'minor': 4, 'patch': 5, 'prerelease': 'pre.2', 'build': 'build.4'}
7885

7986

87+
Checking for a Valid Semver Version
88+
-----------------------------------
89+
90+
If you need to check a string if it is a valid semver version, use the
91+
classmethod :func:`semver.VersionInfo.isvalid`:
92+
93+
.. code-block:: python
94+
95+
>>> VersionInfo.isvalid("1.0.0")
96+
True
97+
>>> VersionInfo.isvalid("invalid")
98+
False
99+
100+
80101
Accessing Parts of a Version
81102
----------------------------
82103

semver.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,21 @@ def replace(self, **parts):
321321
)
322322
raise TypeError(error)
323323

324+
@classmethod
325+
def isvalid(cls, version):
326+
"""Check if the string is a valid semver version
327+
328+
:param str version: the version string to check
329+
:return: True if the version string is a valid semver version, False
330+
otherwise.
331+
:rtype: bool
332+
"""
333+
try:
334+
cls.parse(version)
335+
return True
336+
except ValueError:
337+
return False
338+
324339

325340
def _to_dict(obj):
326341
if isinstance(obj, VersionInfo):
@@ -681,6 +696,13 @@ def createparser():
681696
sb.add_parser("build", help="Bump the build part of the version"),
682697
):
683698
p.add_argument("version", help="Version to raise")
699+
700+
# Create the is-valid subcommand
701+
parser_isvalid = s.add_parser("is-valid",
702+
help="Checks if a string is a valid semver version")
703+
parser_isvalid.set_defaults(which="is-valid")
704+
parser_isvalid.add_argument("version", help="Version to check")
705+
684706
return parser
685707

686708

@@ -697,6 +719,7 @@ def process(args):
697719
if not hasattr(args, "which"):
698720
args.parser.print_help()
699721
raise SystemExit()
722+
700723
elif args.which == "bump":
701724
maptable = {
702725
"major": "bump_major",
@@ -718,6 +741,11 @@ def process(args):
718741
elif args.which == "compare":
719742
return str(compare(args.version1, args.version2))
720743

744+
elif args.which == "is-valid":
745+
if VersionInfo.isvalid(args.version):
746+
return None
747+
raise ValueError("Invalid version %r" % args.version)
748+
721749

722750
def main(cliargs=None):
723751
"""Entry point for the application script
@@ -732,7 +760,8 @@ def main(cliargs=None):
732760
# Save parser instance:
733761
args.parser = parser
734762
result = process(args)
735-
print(result)
763+
if result is not None:
764+
print(result)
736765
return 0
737766

738767
except (ValueError, TypeError) as err:

test_semver.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,8 @@ def test_should_return_versioninfo_with_replaced_parts(version, parts, expected)
803803
def test_replace_raises_ValueError_for_non_numeric_values():
804804
with pytest.raises(ValueError):
805805
VersionInfo.parse("1.2.3").replace(major="x")
806+
807+
808+
def test_should_versioninfo_isvalid():
809+
assert VersionInfo.isvalid("1.0.0") is True
810+
assert VersionInfo.isvalid("foo") is False

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy