Skip to content

Commit

Permalink
Validate version and alias names
Browse files Browse the repository at this point in the history
  • Loading branch information
jimporter committed Mar 29, 2021
1 parent 732a2de commit 2961733
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
- `mike alias` now checks for existing aliases to prevent erroneously setting an
alias for two different versions
- Replace `packaging` dependency with `verspec` for future stability
- Validate version and alias names to ensure they're non-empty and don't
contain a directory separator

[material-mike]: https://squidfunk.github.io/mkdocs-material/setup/setting-up-versioning/#versioning

Expand Down
13 changes: 13 additions & 0 deletions mike/versions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import re
from verspec.loose import LooseVersion as Version


Expand All @@ -14,13 +15,23 @@ def _version_pair(version):

class VersionInfo:
def __init__(self, version, title=None, aliases=[]):
self._check_version(str(version), 'version')
for i in aliases:
self._check_version(i, 'alias')

self.version, name = _version_pair(version)
self.title = name if title is None else title
self.aliases = set(aliases)

if name in self.aliases:
raise ValueError('duplicated version and alias')

@staticmethod
def _check_version(version, kind):
if ( not version or version in ['.', '..'] or
re.search(r'[\\/]', version) ):
raise ValueError('{!r} is not a valid {}'.format(version, kind))

def __eq__(self, rhs):
return (self.version == rhs.version and self.title == rhs.title and
self.aliases == rhs.aliases)
Expand All @@ -39,6 +50,8 @@ def dumps(self):
return json.dumps(self.to_json())

def update(self, title=None, aliases=[]):
for i in aliases:
self._check_version(i, 'alias')
if title is not None:
self.title = title

Expand Down
30 changes: 29 additions & 1 deletion test/unit/test_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,27 @@ def test_create(self):
self.assertEqual(v.title, '1.0')
self.assertEqual(v.aliases, set())

with self.assertRaises(ValueError):
with self.assertRaisesRegex(ValueError, "^'' is not a valid version$"):
VersionInfo('')
with self.assertRaisesRegex(ValueError,
"^'..' is not a valid version$"):
VersionInfo('..')
with self.assertRaisesRegex(ValueError,
"^'foo/bar' is not a valid version$"):
VersionInfo('foo/bar')
with self.assertRaisesRegex(ValueError,
"^'foo/bar' is not a valid version$"):
VersionInfo(Version('foo/bar'))

with self.assertRaisesRegex(ValueError, "^'' is not a valid alias$"):
VersionInfo('1.0', aliases=['latest', ''])
with self.assertRaisesRegex(ValueError, "^'..' is not a valid alias$"):
VersionInfo('1.0', aliases=['..'])
with self.assertRaisesRegex(ValueError,
"^'foo/bar' is not a valid alias$"):
VersionInfo('1.0', aliases=['foo/bar'])
with self.assertRaisesRegex(ValueError,
"^duplicated version and alias$"):
VersionInfo('1.0', aliases=['1.0'])

def test_equality(self):
Expand Down Expand Up @@ -76,6 +96,14 @@ def test_update(self):
'1.0', '1.0.1', ['latest', 'greatest']
))

with self.assertRaisesRegex(ValueError, "^'' is not a valid alias$"):
v.update(aliases=[''])
with self.assertRaisesRegex(ValueError, "^'..' is not a valid alias$"):
v.update(aliases=['..'])
with self.assertRaisesRegex(ValueError,
"^'foo/bar' is not a valid alias$"):
v.update(aliases=['foo/bar'])


class TestVersions(unittest.TestCase):
def test_add(self):
Expand Down

0 comments on commit 2961733

Please sign in to comment.