Thank you for your donations!   Download the book!   Public source code repository  

NatVer

Natural Versioning 1.2

NatVer consists of at least two, up to five integers, separated by dots (and a colon), like so:
<major>.<minor>[.<feature>[.<commit>]][:<count>].

Each update to any of these resets all lesser numbers, except <count>; for instance, incrementing <minor> resets both <feature> and <commit>, if those are present, like so: 
1.2.3.4 --> 1.3.0.0.

Counter is ever-increasing number, it should never be reset or decreased. It is allowed to skip numbers, i.e. to increase <count> for more than 1:
1.2.3.4:123 --> 1.3.0.0:200.

When comparing versions, counter takes precedence over all the other numbers, i.e. versions are compared as if <count> is written at the very front, so:
1.2.3.4:123 < 0.1.2.3:234, because:
123:1.2.3.4 < 234:0.1.2.3.

Items which are not present are considered to be 0, for the purpose of version comparison. For example, these versions are considered to be identical:
1.2 = 1.2.0 = 1.2.0.0 = 1.2.0.0:0.

Counter is used to preserve order when already existing features, components are removed from project, due to issues in implementation, or even design, to be refactored, replaced, or just abandoned. For instance:
0.2.3.4:123 < 0.7.9.23:234 < 0.1.2.3:235

Intention

NatVer aims to provide succinct status of a project, so that difference between any two versions would be a measure of progress. Anything else is communicated via optional sections: pre-release status, meta data and breakage info.

As a developer, it's not easy to foretell what any particular change could, or would, broke for users. So, only own perspective of what has been done can be reliably communicated.

Developers have pretty good sense where their project stands. As such, natural versioning is intended to communicate that standings to others, without binding status of a project to side-effects of current changes, or inevitable breakages, which will eventually fade away, anyway.

Development

During development, version numbers, after change has been made, conveys whole project status compared to a previous status of the same project:
<project>.<component>[.<feature>[.<commit>]].
Note, scope of (possible) breakage is not included in versioning, only status of a project.

Maintenance

Similarly, during debugging, version numbers holds size of a change:
<redesign>.<rework>[.<patch>[.<bug-fix>]].
Again, affected scope (and breakage of user code) is not contained in versioning, only size of a change. For instance, small bug fix could easily cause need for users to rework their usage of a component; for versioning this still is a bug fix.

Prerelease

Prelease information is optional, it consists of - (hyphen) followed by . (dot) separated identifiers consisting of ASCII alphanumerics and - (hyphen). Numeric identifiers are compared as such, alphabetic identifiers are sorted lexicographically. Prerelease versions have lower precedence than the associated normal version. For instance:
1.0.0.0-alpha < 1.0.0.0-alpha.1 < 1.0.0.0-alpha.27 < 1.0.0.0.
This is the same as in SemVer prerelease version info.

Meta data

Meta data is optional, it consists of + (plus sign), followed by any character except ~ (tilde) and whitespace. For compatibility, it's recommended to keep it within ASCII charset. Meta data should be ignored for the purposes of comparing versions, so versions differing only in meta data are considered the same. Examples:
1.0.0-b.31+962,
1.0+20130313144700,
1.0.0.0-beta+exp.sha.5114f85.

Breakage

Breakage data is optional, it consists of ~ (tilde), followed by any character except whitespace. For compatibility, it's recommended to use only ASCII charset. Scope of breakage is encoded by number of ~ (tildes), 1 for <commit> (<bug-fix>), up to 4 for <project> (<redesign>). Breakage data may be empty, merely presence of ~ (tildes) indicates breakage. 

Note, unlike previous optional sections, first section separator (first tilde) is part of breakage information. For instance: 1.0.0.0~~~foo means that foo as a component is now broken, not foo as a feature.

Breakage data can contain multiple items that are broken, e.g. 1.2.3.4~~~foo+bar. Breakage data can be repeated multiple times, if items of different scope are broken, in which case those are sorted by scope in descending order, i.e. largest breakage first. Example:
1.2.3.4~~~foo~~bar.

Breakage data have lower precedence than the associated normal version, and higher breakage have lower precedence than the lower breakage. If two versions are the same, with the same breakage info, version with pre-release data have lower precedence. If two versions are the same, with the same pre-release info, version with breakage data have lower precedence. Otherwise, breakage data have lower precedence to pre-release info, i.e. between two versions which are otherwise the same, the one with breakage has lower precedence than the one with pre-release info. Examples: 
1.0.0-b.31+962~~~foo~~bar
1.0+20130313144700~~baz,bay+bax
1.0.0.0-beta+exp.sha.5114f85~~~~.
Comparisons: 
1.0.0~~~foo < 1.0.0~~bar < 1.0.0,
1.0.0-alpha.2~~bar < 1.0.0~~bar
1.0.0-alpha.2 < 1.0.0-alpha.3~~~foo 
1.0.0.

Regexp

Regexp (with named groups) used to parse NatVer is:

^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)(?:\.(?P<feature>0|[1-9]\d*)(?:\.(?P<commit>0|[1-9]\d*))?)?(?:\:(?P<count>0|[1-9]\d*))?(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<meta>[^~\s]*))?(?:(?P<breaks>\~[^\s]*?))?$ .

It is provided online with examples at: https://regex101.com/r/lqmlXE/2.

The one without named groups is:

^(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?)?(?:\:(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([^~\s]*))?(?:(\~[^\s]*?))?$

and is provided online at https://regex101.com/r/EBiAwB/3.

No comments:

Post a Comment