summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@paylead.fr>2022-02-06 19:40:53 +0100
committerRaphaël Barrois <raphael.barrois@paylead.fr>2022-02-06 19:40:53 +0100
commit7e59a4b2e82abe4338e307b9fe49b072c9537a15 (patch)
treedddcabd343e672bd6a9e86d2bb51f32e2cdb5b4d /docs
parent81a4730778fba6b5c76242d3c8da6dace7e2ec0a (diff)
downloadsemantic-version-7e59a4b2e82abe4338e307b9fe49b072c9537a15.tar.gz
Improve documentation
- The README is now a standalone document, also included as an "introduction" page; - A new "guide" section provides more details on most features; - A couple of typos were fixed. The main goal was to make the README file perfectly suitable for rendering on PyPI, while keeping its content available on the standard documentation on ReadTheDocs.
Diffstat (limited to 'docs')
-rw-r--r--docs/django.rst2
-rw-r--r--docs/guide.rst346
-rw-r--r--[l---------]docs/index.rst31
l---------docs/introduction.rst1
-rw-r--r--docs/reference.rst34
5 files changed, 399 insertions, 15 deletions
diff --git a/docs/django.rst b/docs/django.rst
index 34a0fe3..befa50a 100644
--- a/docs/django.rst
+++ b/docs/django.rst
@@ -37,4 +37,4 @@ with their :attr:`~django.db.models.CharField.max_length` defaulting to 200.
The syntax to use for the field; defaults to ``'simple'``.
- .. versionaddedd:: 2.7
+ .. versionadded:: 2.7
diff --git a/docs/guide.rst b/docs/guide.rst
new file mode 100644
index 0000000..7780a32
--- /dev/null
+++ b/docs/guide.rst
@@ -0,0 +1,346 @@
+Guide
+=====
+
+.. currentmodule:: semantic_version
+
+This module covers the 2.0.0 version of the SemVer scheme, with additional
+extensions:
+
+- Coercing any version string into a SemVer version, through
+ :meth:`Version.coerce`;
+- Comparing versions;
+- Computing next versions;
+- Modelling version range specifcations, and choosing the best match -- for both
+ its custom logic, and NPM semantics (custom range specification schemes can
+ be added).
+
+
+Version basics
+--------------
+
+Building :class:`Version` instances
+"""""""""""""""""""""""""""""""""""
+
+The core of the module is the :class:`Version` class; it is usually instantiated
+from a version string:
+
+.. code-block:: pycon
+
+ >>> import semantic_version as semver
+ >>> v = semver.Version("0.1.1")
+
+The version's components are available through its attributes:
+
+* :attr:`~Version.major`, :attr:`~Version.minor`, :attr:`~Version.patch` are
+ integers:
+
+ .. code-block:: pycon
+
+ >>> v.major
+ 0
+ >>> v.minor
+ 1
+ >>> v.patch
+ 1
+
+
+* The :attr:`~Version.prerelease` and :attr:`~Version.build` attributes are
+ iterables of text elements:
+
+ .. code-block:: pycon
+
+ >>> v2 = semver.Version("0.1.1-dev+23.git2")
+ >>> v2.prerelease
+ ["dev"]
+ >>> v2.build
+ ["23", "git2"]
+
+
+One may also build a :class:`Version` from named components directly:
+
+.. code-block:: pycon
+
+ >>> semantic_version.Version(major=0, minor=1, patch=2)
+ Version('0.1.2')
+
+
+In that case, ``major``, ``minor`` and ``patch`` are mandatory, and must be integers.
+``prerelease`` and ``build``, if provided, must be tuples of strings:
+
+.. code-block:: pycon
+
+ >>> semantic_version.Version(major=0, minor=1, patch=2, prerelease=('alpha', '2'))
+ Version('0.1.2-alpha.2')
+
+
+If the provided version string is invalid, a :exc:`ValueError` will be raised:
+
+.. code-block:: pycon
+
+ >>> semver.Version('0.1')
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ File "/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py", line 64, in __init__
+ major, minor, patch, prerelease, build = self.parse(version_string, partial)
+ File "/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py", line 86, in parse
+ raise ValueError('Invalid version string: %r' % version_string)
+ ValueError: Invalid version string: '0.1'
+
+
+Working with non-SemVer version strings
+"""""""""""""""""""""""""""""""""""""""
+
+Some user-supplied input might not match the semantic version scheme.
+For such cases, the ``Version.coerce`` method will try to convert any
+version-like string into a valid semver version:
+
+.. code-block:: pycon
+
+ >>> semver.Version.coerce('0')
+ Version('0.0.0')
+ >>> semver.Version.coerce('0.1.2.3.4')
+ Version('0.1.2+3.4')
+ >>> semver.Version.coerce('0.1.2a3')
+ Version('0.1.2-a3')
+
+
+Comparing versions
+""""""""""""""""""
+
+Versions can be compared, following the SemVer scheme:
+
+.. code-block:: pycon
+
+ >>> semver.Version("0.1.0") < semver.Version("0.1.1")
+ True
+ >>> max(
+ ... semver.Version("0.1.0"),
+ ... semver.Version("0.2.2"),
+ ... semver.Version("0.1.1"),
+ ... semver.Version("0.2.2-rc1"),
+ ... )
+ Version("0.2.2")
+
+
+.. note::
+
+ As defined in SemVer, build metadata is ignored in comparisons,
+ but not in equalities:
+
+ .. code-block:: pycon
+
+ >>> semver.Version("0.1.2") <= semver.Version("0.1.2+git2")
+ True
+ >>> semver.Version("0.1.2") >= semver.Version("0.1.2+git2")
+ True
+ >>> semver.Version("0.1.2") == semver.Version("0.1.2+git2")
+ False
+
+
+Iterating versions
+""""""""""""""""""
+
+One can get a new version that represents a bump in one of the version levels
+through the :meth:`Version.next_major`, :meth:`Version.next_minor` or
+:meth:`Version.next_patch` functions:
+
+.. code-block:: pycon
+
+ >>> v = semver.Version('0.1.1+build')
+ >>> new_v = v.next_major()
+ >>> str(new_v)
+ '1.0.0'
+ >>> v = semver.Version('1.1.1+build')
+ >>> new_v = v.next_minor()
+ >>> str(new_v)
+ '1.2.0'
+ >>> v = semver.Version('1.1.1+build')
+ >>> new_v = v.next_patch()
+ >>> str(new_v)
+ '1.1.2'
+
+.. note::
+
+ * If the version includes :attr:`~Version.build` or
+ :attr:`~Version.prerelease` metadata, that value will be empty in the
+ next version;
+ * The next patch following a version with a pre-release identifier
+ is the same version with its prerelease and build identifiers removed:
+ ``Version("0.1.1-rc1").next_patch() == Version("0.1.1")``
+ * Pre-release and build naming schemes are often custom and specific
+ to a project's internal design; thus, the library can't provide a
+ ``next_xxx`` method for those fields.
+
+One may also truncate versions through the :meth:`Version.truncate` method,
+removing components beyond the selected level:
+
+.. code-block:: pycon
+
+ >>> v = semver.Version("0.1.2-dev+git3")
+ >>> v.truncate("prerelease")
+ Version("0.1.2-dev")
+ >>> v.truncate("minor")
+ Version("0.1.0")
+
+
+Range specifications
+--------------------
+
+Comparing version numbers isn't always enough; in many situations, one needs to
+define a *range of acceptable versions*.
+
+That notion is not defined in SemVer; moreover, several systems exists, with
+their own notations.
+
+The ``semantic_version`` package provides a couple of implementations for these
+notions:
+
+- :class:`SimpleSpec` is a simple implementation, with reasonable expectations;
+- :class:`NpmSpec` sticks to the NPM specification.
+
+Further schemes can be built in a similar manner, relying on the :class:`BaseSpec`
+class for basics.
+
+Core API
+""""""""
+
+The core API is provided by the :class:`BaseSpec` class.
+
+.. note::
+
+ These examples use :class:`SimpleSpec` in order to be easily reproduced
+ by users, but only exhibit the standard parts of the interface.
+
+It is possible to check whether a given :class:`Version` matches a
+:class:`BaseSpec` through :meth:`~BaseSpec.match`:
+
+.. code-block:: pycon
+
+ >>> s = semver.SimpleSpec(">=0.1.1")
+ >>> s.match(Version("0.1.1"))
+ True
+ >>> s.match(Version("0.1.0"))
+ False
+
+This feature is also available through the ``in`` keyword:
+
+.. code-block:: pycon
+
+ >>> s = semver.SimpleSpec(">=0.1.1")
+ >>> Version("0.1.1") in s
+ True
+ >>> Version("0.1.0") in s
+ False
+
+A specification can filter compatible values from an iterable of versions
+with :meth:`~BaseSpec.filter`:
+
+.. code-block:: pycon
+
+ >>> s = semver.SimpleSpec(">=0.2.1")
+ >>> versions = [
+ ... Version("0.1.0"),
+ ... Version("0.2.0"),
+ ... Version("0.3.0"),
+ ... Version("0.4.0"),
+ ... ]
+ >>> list(s.filter(versions))
+ [Version("0.3.0"), Version("0.4.0")]
+
+It can also select the "best" version from such an iterable through
+:meth:`~BaseSpec.select`:
+
+.. code-block:: pycon
+
+ >>> s = semver.SimpleSpec(">=0.2.1")
+ >>> versions = [
+ ... Version("0.1.0"),
+ ... Version("0.2.0"),
+ ... Version("0.3.0"),
+ ... Version("0.4.0"),
+ ... ]
+ >>> s.select(versions)
+ Version("0.4.0")
+
+
+The :class:`SimpleSpec` scheme
+""""""""""""""""""""""""""""""
+
+The :class:`SimpleSpec` provides a hopefully intuitive version range
+specification scheme:
+
+- A specification expression is composed of comma-separated clauses;
+- Each clause can be:
+
+ - An equality match (``==`` or ``!=``);
+ - A comparison (``>``, ``>=``, ``<`` , ``<=``);
+ - A compatible release clause, PyPI style (``~=2.2`` for ``>=2.2.0,<3.0.0``);
+ - An NPM style clause:
+
+ - ``~1.2.3`` for ``>=1.2.3,<1.3.0``;
+ - ``^1.3.4`` for ``>=1.3.4,<2.0.0``;
+
+- The range in each clause may include a wildcard:
+
+ * ``==0.1.*`` maps to ``>=0.1.0,<0.2.0``;
+ * ``==1.*`` or ``==1.*.*`` map to ``>=1.0.0,<2.0.0``
+
+
+.. rubric:: Special matching rules
+
+When testing a :class:`Version` against a :class:`SimpleSpec`, comparisons are
+adjusted for common user expectations; thus, a pre-release version (``1.0.0-alpha``)
+will not satisfy the ``==1.0.0`` :class:`SimpleSpec`.
+
+Pre-release identifiers will only be compared if included in the :class:`BaseSpec`
+definition or (for the empty pre-release number) if a single dash is appended
+(``1.0.0-``):
+
+
+.. code-block:: pycon
+
+ >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0') # No pre-release identifier
+ False
+ >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0-') # Include pre-release in checks
+ True
+
+
+Build metadata has no ordering; thus, the only meaningful comparison including
+build metadata is equality:
+
+
+.. code-block:: pycon
+
+ >>> Version('1.0.0+build2') in SimpleSpec('<=1.0.0') # Build metadata ignored
+ True
+ >>> Version('1.0.0+build1') in SimpleSpec('==1.0.0+build2') # Include build in checks
+ False
+
+.. note::
+
+ The full documentation is provided in the reference section
+ for the :class:`SimpleSpec` class.
+
+
+The :class:`NpmSpec` scheme
+"""""""""""""""""""""""""""
+
+The :class:`NpmSpec` class implements the full NPM specification (from
+https://docs.npmjs.com/misc/semver.html):
+
+.. code-block:: pycon
+
+ >>> semver.Version("0.1.2") in semver.NpmSpec("0.1.0-alpha.2 .. 0.2.4")
+ True
+ >>> semver.Version('0.1.2') in semver.NpmSpec('>=0.1.1 <0.1.3 || 2.x')
+ True
+ >>> semver.Version('2.3.4') in semver.NpmSpec('>=0.1.1 <0.1.3 || 2.x')
+ True
+
+Using with Django
+-----------------
+
+The :mod:`semantic_version.django_fields` module provides django fields to
+store :class:`Version` or :class:`BaseSpec` objects.
+
+More documentation is available in the :doc:`django` section.
diff --git a/docs/index.rst b/docs/index.rst
index 89a0106..135ee68 120000..100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1 +1,30 @@
-../README.rst \ No newline at end of file
+======================
+python-semanticversion
+======================
+
+.. include:: introduction.rst
+
+
+Contents
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ introduction
+ guide
+ reference
+ django
+ changelog
+ credits
+
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/docs/introduction.rst b/docs/introduction.rst
new file mode 120000
index 0000000..89a0106
--- /dev/null
+++ b/docs/introduction.rst
@@ -0,0 +1 @@
+../README.rst \ No newline at end of file
diff --git a/docs/reference.rst b/docs/reference.rst
index 951bd9a..93a29eb 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -66,6 +66,7 @@ Representing a version (the Version class)
------------------------------------------
.. class:: Version(version_string[, partial=False])
+ :noindex:
Object representation of a `SemVer`_-compliant version.
@@ -90,15 +91,6 @@ Representing a version (the Version class)
.. rubric:: Attributes
- .. attribute:: partial
-
- ``bool``, whether this is a 'partial' or a complete version number.
- Partial version number may lack :attr:`minor` or :attr:`patch` version numbers.
-
- .. deprecated:: 2.7
- The ability to define a partial version will be removed in version 3.0.
- Use :class:`SimpleSpec` instead: ``SimpleSpec('1.x.x')``.
-
.. attribute:: major
``int``, the major version number
@@ -140,6 +132,15 @@ Representing a version (the Version class)
Note that the :attr:`~Version.build` isn't included in the precedence_key computatin.
+ .. attribute:: partial
+
+ ``bool``, whether this is a 'partial' or a complete version number.
+ Partial version number may lack :attr:`minor` or :attr:`patch` version numbers.
+
+ .. deprecated:: 2.7
+ The ability to define a partial version will be removed in version 3.0.
+ Use :class:`SimpleSpec` instead: ``SimpleSpec('1.x.x')``.
+
.. rubric:: Methods
@@ -173,7 +174,7 @@ Representing a version (the Version class)
>>> Version('1.1.0-alpha').next_minor()
Version('1.1.0')
- .. method:: next_patch(self):
+ .. method:: next_patch(self)
Return the next patch version, i.e the smallest version strictly
greater than the current one with empty :attr:`prerelease` and :attr:`build`.
@@ -231,6 +232,7 @@ Representing a version (the Version class)
- For non-:attr:`partial` versions, compare using the `SemVer`_ scheme
- If any compared object is :attr:`partial`:
+
- Begin comparison using the `SemVer`_ scheme
- If a component (:attr:`minor`, :attr:`patch`, :attr:`prerelease` or :attr:`build`)
was absent from the :attr:`partial` :class:`Version` -- represented with :obj:`None`
@@ -472,7 +474,7 @@ Each of those ``Spec`` classes provides a shared set of methods to work with ver
* A clause of ``>0.1.2-rc.3`` will match versions strictly above ``0.1.2-rc.3``, including matching prereleases of ``0.1.2``: ``0.1.2-rc.10`` is included;
* A clause of ``>=XXX`` will match versions that match ``>XXX`` or ``==XXX``
- ..rubric:: Wildcards
+ .. rubric:: Wildcards
* A clause of ``==0.1.*`` is equivalent to ``>=0.1.0,<0.2.0``
* A clause of ``>=0.1.*`` is equivalent to ``>=0.1.0``
@@ -554,7 +556,7 @@ Each of those ``Spec`` classes provides a shared set of methods to work with ver
<SpecItem: != Version('1.1.13', partial=True)>,
)>
- Its keeps a list of :class:`SpecItem` objects, based on the initial expression
+ It keeps a list of :class:`SpecItem` objects, based on the initial expression
components.
.. method:: __iter__(self)
@@ -705,7 +707,13 @@ Each of those ``Spec`` classes provides a shared set of methods to work with ver
>>> Version('1.0.1') in Spec('!=1.0.1')
False
- The kind of 'Almost equal to' specifications
+ .. data:: KIND_COMPATIBLE
+
+ The kind of `compatible release clauses`_
+ specifications::
+
+ >>> Version('1.1.2') in Spec('~=1.1.0')
+ True