Skip to content

Commit df82b34

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 "check" subcommand * Update manpage (pysemver.rst) * Update `CHANGELOG.rst`
1 parent 445f47a commit df82b34

File tree

5 files changed

+83
-3
lines changed

5 files changed

+83
-3
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:`check` 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: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,29 @@ you get an error message and a return code != 0::
8686
ERROR 1.5 is not valid SemVer string
8787

8888

89+
pysemver check
90+
~~~~~~~~~~~~~~
91+
92+
Checks if a string is a valid semver version.
93+
94+
.. code:: bash
95+
96+
pysemver check <VERSION>
97+
98+
.. option:: <VERSION>
99+
100+
The version string to check.
101+
102+
The *error code* returned by the script indicates if the
103+
version is valid (=0) or not (!=0)::
104+
105+
$ pysemver check 1.2.3; echo $?
106+
0
107+
$ pysemver check 2.1; echo $?
108+
ERROR Invalid version '2.1'
109+
2
110+
111+
89112
pysemver compare
90113
~~~~~~~~~~~~~~~~
91114

@@ -121,7 +144,6 @@ are valid (return code 0) or not (return code != 0)::
121144
ERROR 1.2.x is not valid SemVer string
122145
2
123146

124-
125147
See also
126148
--------
127149

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: 31 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,14 @@ 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 check subcommand
701+
parser_check = s.add_parser(
702+
"check", help="Checks if a string is a valid semver version"
703+
)
704+
parser_check.set_defaults(which="check")
705+
parser_check.add_argument("version", help="Version to check")
706+
684707
return parser
685708

686709

@@ -697,6 +720,7 @@ def process(args):
697720
if not hasattr(args, "which"):
698721
args.parser.print_help()
699722
raise SystemExit()
723+
700724
elif args.which == "bump":
701725
maptable = {
702726
"major": "bump_major",
@@ -718,6 +742,11 @@ def process(args):
718742
elif args.which == "compare":
719743
return str(compare(args.version1, args.version2))
720744

745+
elif args.which == "check":
746+
if VersionInfo.isvalid(args.version):
747+
return None
748+
raise ValueError("Invalid version %r" % args.version)
749+
721750

722751
def main(cliargs=None):
723752
"""Entry point for the application script
@@ -732,7 +761,8 @@ def main(cliargs=None):
732761
# Save parser instance:
733762
args.parser = parser
734763
result = process(args)
735-
print(result)
764+
if result is not None:
765+
print(result)
736766
return 0
737767

738768
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