summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS4
-rw-r--r--ChangeLog2
-rw-r--r--LICENSE2
-rw-r--r--README.rst4
-rw-r--r--semantic_version/__init__.py2
-rw-r--r--semantic_version/base.py21
-rw-r--r--semantic_version/compat.py2
-rw-r--r--semantic_version/django_fields.py4
-rwxr-xr-xsetup.py2
-rw-r--r--tests/compat.py2
-rw-r--r--tests/django_test_app/__init__.py2
-rw-r--r--tests/django_test_app/models.py2
-rwxr-xr-xtests/test_base.py130
-rw-r--r--tests/test_django.py41
-rwxr-xr-xtests/test_match.py2
-rwxr-xr-xtests/test_parsing.py2
-rw-r--r--tests/test_spec.py2
17 files changed, 201 insertions, 25 deletions
diff --git a/CREDITS b/CREDITS
index 619b6cc..53fdef1 100644
--- a/CREDITS
+++ b/CREDITS
@@ -18,8 +18,10 @@ Contributors
The project has received contributions from (in alphabetical order):
* Raphaƫl Barrois <raphael.barrois+semver@polytechnique.org> (https://github.com/rbarrois)
-* Michael Hrivnak <mhrivnak@hrivnak.org> (https://github.com/mhrivnak)
* Rick Eyre <rick.eyre@outlook.com> (https://github.com/rickeyre)
+* Hugo Rodger-Brown <hugo@yunojuno.com> (https://github.com/yunojuno)
+* Michael Hrivnak <mhrivnak@hrivnak.org> (https://github.com/mhrivnak)
+* William Minchin <w_minchin@hotmail.com> (https://github.com/minchinweb)
* Dave Hall <skwadhd@gmail.com> (https://github.com/skwashd)
diff --git a/ChangeLog b/ChangeLog
index cd7c3db..0fd7823 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -31,6 +31,8 @@ ChangeLog
parameters differ only by build metadata
* ``Spec('<=1.3.0')`` now matches ``Version('1.3.0+abde24fe883')``
+ * `#24 <https://github.com/rbarrois/python-semanticversion/issues/24>`_: Fix handling of bumping pre-release versions, thanks to @minchinweb.
+
2.4.2 (2015-07-02)
------------------
diff --git a/LICENSE b/LICENSE
index 726ce95..66aba18 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2014 The python-semanticversion project
+Copyright (c) The python-semanticversion project
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.rst b/README.rst
index 484692e..7389009 100644
--- a/README.rst
+++ b/README.rst
@@ -7,7 +7,7 @@ It follows strictly the 2.0.0 version of the SemVer scheme.
.. image:: https://secure.travis-ci.org/rbarrois/python-semanticversion.png?branch=master
:target: http://travis-ci.org/rbarrois/python-semanticversion/
-semantic_version supports Python 2.6, 2.7, 3.2, 3.3, 3.4; and is distributed under the two-clause BSD licence.
+semantic_version supports Python 2.6, 2.7, 3.2, 3.3, 3.4; and is distributed under the two-clause BSD license.
Links
-----
@@ -293,7 +293,7 @@ When submitting patches or pull requests, you should respect the following rules
.. note:: All files should contain the following header::
# -*- encoding: utf-8 -*-
- # Copyright (c) 2012-2014 The python-semanticversion project
+ # Copyright (c) The python-semanticversion project
Contents
diff --git a/semantic_version/__init__.py b/semantic_version/__init__.py
index 07de3a5..94e0a8d 100644
--- a/semantic_version/__init__.py
+++ b/semantic_version/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
diff --git a/semantic_version/base.py b/semantic_version/base.py
index d0f5db8..7451e14 100644
--- a/semantic_version/base.py
+++ b/semantic_version/base.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
from __future__ import unicode_literals
@@ -89,15 +89,24 @@ class Version(object):
return int(value)
def next_major(self):
- return Version('.'.join(str(x) for x in [self.major + 1, 0, 0]))
+ if self.prerelease and self.minor is 0 and self.patch is 0:
+ return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch]))
+ else:
+ return Version('.'.join(str(x) for x in [self.major + 1, 0, 0]))
def next_minor(self):
- return Version(
- '.'.join(str(x) for x in [self.major, self.minor + 1, 0]))
+ if self.prerelease and self.patch is 0:
+ return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch]))
+ else:
+ return Version(
+ '.'.join(str(x) for x in [self.major, self.minor + 1, 0]))
def next_patch(self):
- return Version(
- '.'.join(str(x) for x in [self.major, self.minor, self.patch + 1]))
+ if self.prerelease:
+ return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch]))
+ else:
+ return Version(
+ '.'.join(str(x) for x in [self.major, self.minor, self.patch + 1]))
@classmethod
def coerce(cls, version_string, partial=False):
diff --git a/semantic_version/compat.py b/semantic_version/compat.py
index 4dd60fe..b17468f 100644
--- a/semantic_version/compat.py
+++ b/semantic_version/compat.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
diff --git a/semantic_version/django_fields.py b/semantic_version/django_fields.py
index a0c6979..eba8658 100644
--- a/semantic_version/django_fields.py
+++ b/semantic_version/django_fields.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
from __future__ import unicode_literals
@@ -18,7 +18,7 @@ class BaseSemVerField(models.CharField):
super(BaseSemVerField, self).__init__(*args, **kwargs)
def get_prep_value(self, obj):
- return str(obj)
+ return None if obj is None else str(obj)
def get_db_prep_value(self, value, connection, prepared=False):
if not prepared:
diff --git a/setup.py b/setup.py
index b8e164a..6baac7d 100755
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
import codecs
diff --git a/tests/compat.py b/tests/compat.py
index f3617ee..f3ef508 100644
--- a/tests/compat.py
+++ b/tests/compat.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
import sys
diff --git a/tests/django_test_app/__init__.py b/tests/django_test_app/__init__.py
index 72ebf68..0f94470 100644
--- a/tests/django_test_app/__init__.py
+++ b/tests/django_test_app/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
try: # pragma: no cover
diff --git a/tests/django_test_app/models.py b/tests/django_test_app/models.py
index 06d0096..5313e89 100644
--- a/tests/django_test_app/models.py
+++ b/tests/django_test_app/models.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
try:
from django.db import models
diff --git a/tests/test_base.py b/tests/test_base.py
index ae23d86..6b64073 100755
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
"""Test the various functions from 'base'."""
@@ -241,19 +241,119 @@ class VersionTestCase(unittest.TestCase):
self.assertTrue(v != '0.1.0')
self.assertFalse(v == '0.1.0')
- def test_bump_versions(self):
+ def test_bump_clean_versions(self):
+ # We Test each property explicitly as the == comparator for versions
+ # does not distinguish between prerelease or builds for equality.
+
+ v = base.Version('1.0.0+build')
+ v = v.next_major()
+ self.assertEqual(v.major, 2)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.0+build')
+ v = v.next_minor()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 1)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.0+build')
+ v = v.next_patch()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 1)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.1.0+build')
+ v = v.next_major()
+ self.assertEqual(v.major, 2)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.1.0+build')
+ v = v.next_minor()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 2)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.1.0+build')
+ v = v.next_patch()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 1)
+ self.assertEqual(v.patch, 1)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1+build')
+ v = v.next_major()
+ self.assertEqual(v.major, 2)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1+build')
+ v = v.next_minor()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 1)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1+build')
+ v = v.next_patch()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 2)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ def test_bump_prerelease_versions(self):
# We Test each property explicitly as the == comparator for versions
# does not distinguish between prerelease or builds for equality.
v = base.Version('1.0.0-pre+build')
v = v.next_major()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.0-pre+build')
+ v = v.next_minor()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.0-pre+build')
+ v = v.next_patch()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.1.0-pre+build')
+ v = v.next_major()
self.assertEqual(v.major, 2)
self.assertEqual(v.minor, 0)
self.assertEqual(v.patch, 0)
self.assertEqual(v.prerelease, ())
self.assertEqual(v.build, ())
- v = base.Version('1.0.1-pre+build')
+ v = base.Version('1.1.0-pre+build')
v = v.next_minor()
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 1)
@@ -265,6 +365,30 @@ class VersionTestCase(unittest.TestCase):
v = v.next_patch()
self.assertEqual(v.major, 1)
self.assertEqual(v.minor, 1)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1-pre+build')
+ v = v.next_major()
+ self.assertEqual(v.major, 2)
+ self.assertEqual(v.minor, 0)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1-pre+build')
+ v = v.next_minor()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 1)
+ self.assertEqual(v.patch, 0)
+ self.assertEqual(v.prerelease, ())
+ self.assertEqual(v.build, ())
+
+ v = base.Version('1.0.1-pre+build')
+ v = v.next_patch()
+ self.assertEqual(v.major, 1)
+ self.assertEqual(v.minor, 0)
self.assertEqual(v.patch, 1)
self.assertEqual(v.prerelease, ())
self.assertEqual(v.build, ())
diff --git a/tests/test_django.py b/tests/test_django.py
index 94e2420..c93dde7 100644
--- a/tests/test_django.py
+++ b/tests/test_django.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
from __future__ import unicode_literals
@@ -30,6 +30,13 @@ if django_loaded and django.VERSION < (1, 7): # pragma: no cover
except ImportError:
pass
+# the refresh_from_db method only came in with 1.8, so in order to make this
+# work will all supported versions we have our own function.
+def save_and_refresh(obj):
+ """Saves an object, and refreshes from the database."""
+ obj.save()
+ obj = obj.__class__.objects.get(id=obj.id)
+
@unittest.skipIf(not django_loaded, "Django not installed")
class DjangoFieldTestCase(unittest.TestCase):
@@ -48,6 +55,38 @@ class DjangoFieldTestCase(unittest.TestCase):
obj.full_clean()
+ def test_version_save(self):
+ """Test saving object with a VersionField."""
+ # first test with a null value
+ obj = models.PartialVersionModel()
+ self.assertIsNone(obj.id)
+ self.assertIsNone(obj.optional)
+ save_and_refresh(obj)
+ self.assertIsNotNone(obj.id)
+ self.assertIsNone(obj.optional_spec)
+
+ # now set to something that is not null
+ spec = semantic_version.Spec('==0,!=0.2')
+ obj.optional_spec = spec
+ save_and_refresh(obj)
+ self.assertEqual(obj.optional_spec, spec)
+
+ def test_spec_save(self):
+ """Test saving object with a SpecField."""
+ # first test with a null value
+ obj = models.PartialVersionModel()
+ self.assertIsNone(obj.id)
+ self.assertIsNone(obj.optional_spec)
+ save_and_refresh(obj)
+ self.assertIsNotNone(obj.id)
+ self.assertIsNone(obj.optional_spec)
+
+ # now set to something that is not null
+ spec = semantic_version.Spec('==0,!=0.2')
+ obj.optional_spec = spec
+ save_and_refresh(obj)
+ self.assertEqual(obj.optional_spec, spec)
+
def test_partial_spec(self):
obj = models.VersionModel(version='0.1.1', spec='==0,!=0.2')
self.assertEqual(semantic_version.Version('0.1.1'), obj.version)
diff --git a/tests/test_match.py b/tests/test_match.py
index 473abfc..9955b9f 100755
--- a/tests/test_match.py
+++ b/tests/test_match.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
import unittest
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index c7651d2..8fd22da 100755
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
import itertools
diff --git a/tests/test_spec.py b/tests/test_spec.py
index a13cb0b..43c9d6a 100644
--- a/tests/test_spec.py
+++ b/tests/test_spec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (c) 2012-2014 The python-semanticversion project
+# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.
"""Test conformance to the specs."""