Skip to content

Commit

Permalink
Integrate with Read the Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Jun 15, 2023
1 parent 0375d0d commit 2e2d722
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 22 deletions.
13 changes: 13 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

build:
os: ubuntu-22.04
tools:
python: "3.11"

mkdocs:
configuration: mkdocs.yaml

python:
install:
- requirements: docs/requirements.txt
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ Development requires Python 3.7+.
```
poetry run pytest --cov
```
* Render documentation:
```
pipx install mkdocs
pipx runpip mkdocs install -r docs/requirements.txt
mkdocs serve
```
3 changes: 3 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# API

::: dunamai
2 changes: 2 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mkdocstrings[python]
mkdocs-material
114 changes: 92 additions & 22 deletions dunamai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,56 @@


class Style(Enum):
"""
Standard styles for serializing a version.
"""

Pep440 = "pep440"
"""PEP 440"""
SemVer = "semver"
"""Semantic Versioning"""
Pvp = "pvp"
"""Haskell Package Versioning Policy"""


class Vcs(Enum):
"""
Version control systems.
"""

Any = "any"
"""Automatically determine the VCS."""
Git = "git"
"""Git"""
Mercurial = "mercurial"
"""Mercurial"""
Darcs = "darcs"
"""Darcs"""
Subversion = "subversion"
"""Subversion"""
Bazaar = "bazaar"
"""Bazaar"""
Fossil = "fossil"
"""Fossil"""
Pijul = "pijul"
"""Pijul"""


class Pattern(Enum):
"""
Regular expressions used to parse tags as versions.
"""

Default = "default"
"""Default pattern, including `v` prefix."""
DefaultUnprefixed = "default-unprefixed"
"""Default pattern, but without `v` prefix."""

def regex(self) -> str:
"""
Get the regular expression for this preset pattern.
:returns: Regular expression.
"""
variants = {
Pattern.Default: VERSION_SOURCE_PATTERN,
Expand All @@ -106,6 +133,9 @@ def parse(pattern: Union[str, "Pattern"]) -> str:
If the pattern contains the capture group `?P<base>`, then it is
returned as-is. Otherwise, it is interpreted as a variant of the
`Pattern` enum.
:param pattern: Pattern to parse.
:returns: Regular expression.
"""
if isinstance(pattern, str) and "?P<base>" in pattern:
return pattern
Expand All @@ -126,9 +156,20 @@ def parse(pattern: Union[str, "Pattern"]) -> str:


class Concern(Enum):
"""
A concern/warning discovered while producing the version.
"""

ShallowRepository = "shallow-repository"
"""Repository does not contain full history"""

def message(self) -> str:
"""
Produce a human-readable description of the concern.
:returns: Concern description.
"""

if self == Concern.ShallowRepository:
return "This is a shallow repository, so Dunamai may not produce the correct version."
else:
Expand Down Expand Up @@ -188,7 +229,7 @@ def _match_version_pattern(
pattern: Union[str, Pattern], sources: Sequence[str], latest_source: bool
) -> _MatchedVersionPattern:
"""
:return: Tuple of:
:returns: Tuple of:
* matched tag
* base segment
* tuple of:
Expand Down Expand Up @@ -465,6 +506,33 @@ def from_git_tag_topo_order(tag_branch: str) -> Mapping[str, int]:

@total_ordering
class Version:
"""
A dynamic version.
:ivar base: Release segment.
:vartype base: str
:ivar stage: Alphabetical part of prerelease segment.
:vartype stage: Optional[str]
:ivar revision: Numerical part of prerelease segment.
:vartype revision: Optional[int]
:ivar distance: Number of commits since the last tag.
:vartype distance: int
:ivar commit: Commit ID.
:vartype commit: Optional[str]
:ivar dirty: Whether there are uncommitted changes.
:vartype dirty: Optional[bool]
:ivar tagged_metadata: Any metadata segment from the tag itself.
:vartype tagged_metadata: Optional[str]
:ivar epoch: Optional PEP 440 epoch.
:vartype epoch: Optional[int]
:ivar branch: Name of the current branch.
:vartype branch: Optional[str]
:ivar timestamp: Timestamp of the current commit.
:vartype timestamp: Optional[dt.datetime]
:ivar concerns: Any concerns regarding the version.
:vartype concerns: Optional[Set[Concern]]
"""

def __init__(
self,
base: str,
Expand Down Expand Up @@ -493,33 +561,22 @@ def __init__(
:param timestamp: Timestamp of the current commit.
:param concerns: Any concerns regarding the version.
"""
#: Release segment.
self.base = base
#: Alphabetical part of prerelease segment.
self.stage = None
#: Numerical part of prerelease segment.
self.revision = None
if stage is not None:
self.stage, self.revision = stage
#: Number of commits since the last tag.
self.distance = distance
#: Commit ID.
self.commit = commit
#: Whether there are uncommitted changes.
self.dirty = dirty
#: Any metadata segment from the tag itself.
self.tagged_metadata = tagged_metadata
#: Optional PEP 440 epoch.
self.epoch = epoch
#: Name of the current branch.
self.branch = branch
#: Timestamp of the current commit.
try:
self.timestamp = timestamp.astimezone(dt.timezone.utc) if timestamp else None
except ValueError:
# Will fail for naive timestamps before Python 3.6.
self.timestamp = timestamp
#: Any concerns regarding the version.
self.concerns = concerns or set()

self._matched_tag = None # type: Optional[str]
Expand Down Expand Up @@ -569,7 +626,7 @@ def _matches_partial(self, other: "Version") -> bool:
Distance is also ignored when `other.distance == 0`.
:param other: The version to compare to.
:return: True if this version equals the other version.
:returns: True if this version equals the other version.
"""
return (
_equal_if_set(self.base, other.base)
Expand Down Expand Up @@ -652,6 +709,7 @@ def serialize(
:param tagged_metadata: If true, insert the `tagged_metadata` in the
version as the first part of the metadata segment.
This is ignored when `format` is used.
:returns: Serialized version.
"""
base = self.base
revision = self.revision
Expand Down Expand Up @@ -764,6 +822,7 @@ def parse(cls, version: str, pattern: Union[str, Pattern] = Pattern.Default) ->
:param version: Full version, such as 0.3.0a3+d7.gb6a9020.dirty.
:param pattern: Regular expression matched against the version.
Refer to `from_any_vcs` for more info.
:returns: Parsed version.
"""
normalized = version
if not version.startswith("v") and pattern in [VERSION_SOURCE_PATTERN, Pattern.Default]:
Expand Down Expand Up @@ -846,13 +905,13 @@ def bump(self, index: int = -1, increment: int = 1) -> "Version":
The base is bumped unless there is a stage defined, in which case,
the revision is bumped instead.
:param index: Numerical position to increment in the base. Default: -1.
:param index: Numerical position to increment in the base.
This follows Python indexing rules, so positive numbers start from
the left side and count up from 0, while negative numbers start from
the right side and count down from -1.
Only has an effect when the base is bumped.
:param increment: By how much to increment the relevant position. Default: 1.
:return: Bumped version.
:param increment: By how much to increment the relevant position.
:returns: Bumped version.
"""
bumped = copy.deepcopy(self)
if bumped.stage is None:
Expand Down Expand Up @@ -918,6 +977,7 @@ def from_git(
:param full_commit: Get the full commit hash instead of the short form.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
archival = _find_higher_file(".git_archival.json", ".git")
if archival is not None:
Expand Down Expand Up @@ -1133,6 +1193,7 @@ def from_mercurial(
:param full_commit: Get the full commit hash instead of the short form.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
archival = _find_higher_file(".hg_archival.txt", ".hg")
if archival is not None:
Expand Down Expand Up @@ -1257,6 +1318,7 @@ def from_darcs(
until there is a match.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
_detect_vcs(Vcs.Darcs)

Expand Down Expand Up @@ -1324,6 +1386,7 @@ def from_subversion(
:param tag_dir: Location of tags relative to the root.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
_detect_vcs(Vcs.Subversion)

Expand Down Expand Up @@ -1409,6 +1472,7 @@ def from_bazaar(
until there is a match.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
_detect_vcs(Vcs.Bazaar)

Expand Down Expand Up @@ -1489,6 +1553,7 @@ def from_fossil(
match. If false, keep looking at tags until there is a match.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
_detect_vcs(Vcs.Fossil)

Expand Down Expand Up @@ -1599,6 +1664,7 @@ def from_pijul(
until there is a match.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
_detect_vcs(Vcs.Pijul)

Expand Down Expand Up @@ -1750,6 +1816,7 @@ def from_any_vcs(
This is only used for Git and Mercurial.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
vcs = _detect_vcs_from_archival()
if vcs is None:
Expand Down Expand Up @@ -1789,6 +1856,7 @@ def from_vcs(
This is only used for Git and Mercurial.
:param strict: Elevate warnings to errors.
When there are no tags, fail instead of falling back to 0.0.0.
:returns: Detected version.
"""
return cls._do_vcs_callback(
vcs, pattern, latest_tag, tag_dir, tag_branch, full_commit, strict
Expand Down Expand Up @@ -1833,6 +1901,7 @@ def check_version(version: str, style: Style = Style.Pep440) -> None:
:param version: Version to check.
:param style: Style against which to check.
:raises ValueError: If the version is invalid.
"""
name, pattern = {
Style.Pep440: ("PEP 440", _VALID_PEP440),
Expand Down Expand Up @@ -1874,6 +1943,7 @@ def get_version(
:param parser: Callback to convert a string into a Version instance.
This will be used for the second choice.
For example, you can pass `Version.parse` here.
:returns: First available version.
"""
if ignore is None:
ignore = []
Expand Down Expand Up @@ -1924,7 +1994,7 @@ def serialize_pep440(
:param dev: Developmental release number.
:param epoch: Epoch number.
:param metadata: Any local version label segments.
:return: Serialized version.
:returns: Serialized version.
"""
out = [] # type: list

Expand Down Expand Up @@ -1969,7 +2039,7 @@ def serialize_semver(
:param base: Version core, such as 0.1.0.
:param pre: Pre-release identifiers.
:param metadata: Build metadata identifiers.
:return: Serialized version.
:returns: Serialized version.
"""
out = [base]

Expand All @@ -1992,7 +2062,7 @@ def serialize_pvp(base: str, metadata: Optional[Sequence[Union[str, int]]] = Non
:param base: Version core, such as 0.1.0.
:param metadata: Version tag metadata.
:return: Serialized version.
:returns: Serialized version.
"""
out = [base]

Expand All @@ -2010,12 +2080,12 @@ def bump_version(base: str, index: int = -1, increment: int = 1) -> str:
:param base: Version core, such as 0.1.0.
Do not include pre-release identifiers.
:param index: Numerical position to increment. Default: -1.
:param index: Numerical position to increment.
This follows Python indexing rules, so positive numbers start from
the left side and count up from 0, while negative numbers start from
the right side and count down from -1.
:param increment: By how much the `index` needs to increment. Default: 1.
:return: Bumped version.
:param increment: By how much the `index` needs to increment.
:returns: Bumped version.
"""
bases = [int(x) for x in base.split(".")]
bases[index] += increment
Expand Down
13 changes: 13 additions & 0 deletions mkdocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
site_name: Dunamai Docs

theme:
name: material

plugins:
- search
- mkdocstrings:
handlers:
python:
options:
show_root_toc_entry: false
docstring_style: sphinx

0 comments on commit 2e2d722

Please sign in to comment.