NUT Semantic Versioning
=======================

//////////////////////////////////////////////////////////////////////////////
// You can find a rendered variant of this document on the web at
// https://networkupstools.org/docs/developer-guide.chunked/versioning.html
//////////////////////////////////////////////////////////////////////////////

Historic note
-------------

Historically, the Network UPS Tools project release and interim iterations
code base versions were identified by three or four numeric components,
roughly following the Semantic Versioning (SEMVER) traditions, later
codified as a formal standard at link:https://semver.org/[semver.org]:

* NUT uses the GNU autotools suite for recipe orchestration, and the version
  string is specified in the `configure.ac` file an `AC_INIT` macro, which
  further generates variables like `PACKAGE_VERSION`, `PACKAGE_URL` and others
  used (substituted) in the actual code base, often via `nut_version.h` file.
* NUT releases were identified by a `MAJOR.MINOR.PATCH` triplet, which
  was not strictly following the standard in that while the "major" part
  did reflect architectural/design changes, and "minor" part reflected some
  significant development milestones or API changes, the "patch" part did
  not correspond to post-release fixes but reflected iterative development,
  of which releases were the better-reviewed snapshots. Such a triplet was
  only spelled in `AC_INIT` for the commit tagged as that release.
* Until NUT v2.6.x, the odd values of the `MINOR` component meant development
  code trees, and even values meant the stable tree. This approach was
  skipped (or effectively abandoned, as over a decade passed) with the
  move to Git branches for development -- as numerous NUT v2.7.x based
  releases were produced, and development continued into NUT v2.8.x.
+
NOTE: The project reserves an option to return to the even-odd cadence
(and perhaps proper major-minor-patch versioning on stable tree) later.

* NUT development versions were specified by the next commit after a
  release was published, spelling an `AC_INIT` macro argument like
  `MAJOR.MINOR.PATCH.1` to provide a fourth component -- which is
  logically "greater than" `MAJOR.MINOR.PATCH` for comparisons, so that
  the developed version can formally be installed over a preceding
  release (e.g. from custom testing packages).

This configuration with a single development version (`.1`) was not very
helpful for the faster pace of iterations, especially as the Git workflow
and pull requests were adopted as the way of iterating the NUT development.
This did not really help identify the build being tested by CI or reported
by a community member, nor quickly determine if one custom build is "newer"
than another (e.g. can be a recommended upgrade from the previously installed
snapshot to check if some bug was fixed).

Some experiments were done adding the `git describe` output to version
banners reported by programs. These provide the number of commits since
the most-recent known git tag, as well as the git hash of the NUT sources
involved. This made the builds better identifiable, but did not help
compare the feature branches and the main trunk of development: any code
committed after a release has its own count of commits since that tag,
this one number does not really suffice.

Current NUT SEMVER definition
-----------------------------

Since NUT v2.8.3, the definition which goes into `AC_INIT` and further into
the code was extended in a manner similar to what `git describe` produces,
but with added numbers after the common triplet of semantically versioned
numbers: `X.Y.Z(.T(.B(-C+H(+R))))` or `X.Y.Z(.T(.B(-R)))`

* Standard semver (used in releases):
+
NOTE: Historically NUT did not *diligently* follow the standard semver triplet,
primarily because a snapshot of trunk is tested and released, and work
moves on with the PATCH part (rarely MINOR one) incremented; no actual
patches are released to some sustaining track of an older release lineage.
There were large re-designs that got MAJOR up to 2, though.

  - `X`: MAJOR - incompatible API changes
  - `Y`: MINOR - major new features and/or API evolution
  - `Z`: PATCH - bug fixes (and new features like added drivers)
* Extended semver (for snapshots of trunk):
  - T: (optional) Commits on trunk since previous release tag
* Extended semver (for features branched off trunk):
  - B: (optional) Commits on branch since nearest ancestor which is on trunk

The optional suffix (only for commits which are not git tags themselves)
is provided by `git describe`:

* C: Commits on branch since previous release tag
* H: (Short) Git hash (prefixed by "g" character) of the described commit

The pre-release information (if provided/known) would either follow the
optional suffix detailed above, or it would be the suffix itself:

* R: If this commit has a non-release tag, it can be optionally reported
     so we know that a commit some '1234' iterations after release 'N' is
     also a release candidate for 'N+1'. Note that any dash in that tag value
     will be replaced by a plus, e.g. `2.8.2.2878.1-2879+g882dd4b00+v2.8.3+rc6`

The numeric part of NUT SEMVER definition mostly follows https://semver.org/
except that for development iterations the base version may have up to
five dot-separated numeric components (SEMVER triplet for base release,
and additional data described above). Unlike standard semver provisions
for "pre-release versions" (separated by a minus sign after the triplet),
which are "less than" that release for comparisons, the fourth and fifth
components (if present) are "greater than" that release and any preceding
development iterations made after it.

Helper script `tools/gitlog2version.sh` is used to determine the project
version from packager-provided override files (or equivalents provided by
`make dist` in a snapshot/release tarball), git metadata from the current
workspace, or built-in fallback defaults.

Occasionally there may be tagged pre-releases, which follow the standard
semver markup, like `v2.8.0-rc3` (in git), however they would be converted
to NUT SEMVER here (as a number of commits since previous release) by default.

A special case, which can mostly be seen in CI builds, concerns shallow git
checkouts -- when the currently built commit history is "grafted" (perhaps
down to there being only one commit in the whole git index), and we do not
know of any intersections with git tags or development trunk.  In this case,
the script may not only fall back to a built-in version following a legacy
`X.Y.Z.1` pattern for non-release builds (like `2.8.3.1`), but would also
append a `-0-g{HASH}` suffix to the long values (`VER5`, `VER50`, `DECS5`,
`DESC50`) yielding e.g. `2.8.3.1.0-0+gb3f21f9` for a build from a shallow
git checkout of commit `b3f21f9` of a code base which otherwise fell back
to `2.8.3.1` hard-coded in its copy of the script (bumped by a maintainer
as part of the release process).

Using gitlog2version.sh
-----------------------

The script can be controlled by environment variables, including some sourced
from configuration files. It identifies a number of data items, and reports
the one specified by `NUT_VERSION_QUERY` on `stdout`.

NOTE: It does not currently have a query to report "everything" in a manner
that can be processed by `eval` in calling shell scripts (or `Makefile` rule
implementations).

.Environment variables that can be used for external configuration
[opts="header",cols="1,3,2a"]
|=========================================================================
|Variable	| Description	| Example
|`abs_top_srcdir`	| Top source directory	| * `/home/abuild/nut`
|`abs_top_builddir`	| Top build directory (defaults to `abs_top_srcdir`)
			| * `/home/abuild/.builds/linux/nut`
|`NUT_VERSION_FORCED`	| Set `NUT_VERSION_DEFAULT` (extended NUT SEMVER,
			  may be just a triplet) to this value and enforce
			  `NUT_VERSION_PREFER_GIT=false`. Usually sourced
			  from `${abs_top_srcdir}/VERSION_FORCED` (if present)
			| * `2.8.2.2379`
			  * `2.8.3-rc3`
			  * `2.8.2.2878.3-2881+g45029249f+v2.8.3+rc6`
|`NUT_VERSION_FORCED_SEMVER`	| Set `SEMVER` (exactly a triplet) to this value
			  regardless of `NUT_VERSION_PREFER_GIT` setting. Usually
			  sourced from `${abs_top_srcdir}/VERSION_FORCED_SEMVER`
			  (if present)
			| * `2.8.3`
|`NUT_VERSION_DEFAULT`	| Usually sourced from either
			  `${abs_top_builddir}/VERSION_DEFAULT` (if present)
			  or `${abs_top_srcdir}/VERSION_DEFAULT` (if present),
			  in which case the script also defaults
			  `NUT_VERSION_PREFER_GIT=false` (unless it is already
			  specified as `true` or `${abs_top_srcdir}/.git` exists).
			  If no value was provided, a hard-coded value is used
			  (updated as part of maintainers' release rituals).
			| * `2.8.2.2379.2-2381+g1faa9945d`
|`NUT_VERSION_PREFER_GIT`	| If not provided by caller, or sourced files,
			  or defaulted with `NUT_VERSION_FORCED` or
			  `NUT_VERSION_DEFAULT` as described above, as a `false`
			  value, then becomes `true` if `${abs_top_srcdir}/.git`
			  exists or `false` otherwise (tarball builds) | * `true`
|`NUT_WEBSITE`	| Default website URL, extended for historic sub-sites for
			  a release	| * `https://www.networkupstools.org/`
|`NUT_VERSION_GIT_TRUNK`	| Git branch name to use for calculation of
			  current codebase distance from main development (as known
			  in local workspace index); by default, the newest branch named
			  like `master` is located (any competition is same or ancestor)
			| * `origin/master`
|`NUT_VERSION_GIT_ALL_TAGS`	| If `true`, consider usual (not "annotated")
			  tags too	| * `false`
|`NUT_VERSION_GIT_ALWAYS_DESC`	| If `true`, tell git to return just a commit
			  hash if no tag was matched in index.	| * `false`
|=========================================================================

.Intermediate variables in Git workspace processing
[opts="header",cols="1,3,2a"]
|=========================================================================
|Variable	| Description	| Example (development and release)
|`DESC`	| Originates from `git describe`, filtered for releases (`vX.Y.Z`)
		  and ignoring various `rc`, `alpha`, `beta` etc. tags.
		  This yields the tag name, followed by number of commits added to
		  current `HEAD` history since that tag, and the current commit hash.
		  In the resulting string, the git hash is separated by a "plus"
		  sign (as semver build metadata) rather than the "minus" returned
		  by the tool.
		  | * `v2.8.2-2381+g1faa9945d`
|`TAG`	| Nearest (annotated by default) tag preceding the `HEAD` in history:
		  the part of `DESC` before the commit count and hash.	| * `v2.8.2`
|`BASE`	| The `git merge-base` of current commit and `NUT_VERSION_GIT_TRUNK`
		  (see above). How much of the known trunk history is in current HEAD?
		  This may be "all of it" when we are on that branch or PR made from
		  its tip, "some of it" if looking at a historic snapshot, or "nothing"
		  if looking at the tagged commit (it is the merge base for itself and
		  any of its descendants)	| * `e9a48c9afeb4e06c758a3f4215977445c0f64780`
|`SUFFIX`	| Commit count since the tag and hash of the `HEAD` commit;
			  empty e.g. when `HEAD` is the tagged commit	| * `-2381+g1faa9945d`
|`VER5`	| Full 5-component version, note we strip leading `v` from the expected
		  `TAG` value	| * `2.8.2.2379.2`
|`DESC5`	| Full 5-component version `VER5` concatenated with `SUFFIX`
			| * `2.8.2.2379.2-2381+g1faa9945d`
|`VER50`	| `VER5` without trailing `.0` in fifth or fourth component
			| * dev: `2.8.2.2379.2`
			  * trunk: `2.8.2.2379.0` => `2.8.2.2379`
			  * release: `2.8.2.0.0` => `2.8.2`
|`DESC50`	| `VER50` concatenated with `SUFFIX`
			| * release: `2.8.2-2381-g1faa9945d`
|`SEMVER`	| Exactly three leading numeric components.
			  Either `NUT_VERSION_FORCED_SEMVER` (if provided by caller or
			  configuration files), or derived from `VER5` (removing fourth
			  and fifth numbers)	| * `2.8.0`
|=========================================================================

.Intermediate variables in default (non-git -- tarball or forced) processing
[opts="header",cols="1,3,2a"]
|=========================================================================
|Variable	| Description	| Example (development and release)
|`NUT_VERSION_DEFAULT_DOTS`	| Processed from `NUT_VERSION_DEFAULT` (see above)
			  to count just the dot characters
			| * dev: `....`
			  * trunk: `...`
			  * release: `..`
|`NUT_VERSION_DEFAULT5_DOTS`	| Grows from `NUT_VERSION_DEFAULT_DOTS`,
			  used to construct `NUT_VERSION_DEFAULT5`
			| * `....`
|`NUT_VERSION_DEFAULT5`	| Constructed from `NUT_VERSION_DEFAULT`, adding `.0`
			  numeric components as needed, to have *at least 5* of them
			| * `2.8.2.0.0`
|`NUT_VERSION_DEFAULT3_DOTS`	| Decreases from `NUT_VERSION_DEFAULT_DOTS`,
			  used to construct `NUT_VERSION_DEFAULT3`	| * `..`
|`NUT_VERSION_DEFAULT3`	| Constructed from `NUT_VERSION_DEFAULT`, adding `.0`
			  numeric components as needed or dropping extras, to have
			  *exactly 3* of them
			| * `2.8.0`
|`SUFFIX`		| Empty, unless `NUT_VERSION_DEFAULT` had a suffix
			  for pre-release information roughly matching the
			  `-(rc\|alpha\|beta)[0-9]*` regular expression
			| * `""`
			  * `-rc6`
|`VER5`			| Full 5-component version, `NUT_VERSION_DEFAULT5`
			| * `2.8.2.2379.2`
|`DESC5`		| Constructed as `${VER5}${SUFFIX}`
			| * `2.8.2.2379.2`
			  * `2.8.3.0.0-rc6`
|`VER50`		| `NUT_VERSION_DEFAULT` as provided by caller or
			  defaulted, may be with or without trailing `.0` in fifth or
			  fourth components
			| * `2.8.2.1`
|`DESC50`		| Constructed as `${VER50}${SUFFIX}`
			| * `2.8.2.1`
			  * `2.8.3-rc6`
|`BASE`			| Empty (no known common commits with no trunk)	| * `""`
|`SEMVER`		| Exactly three leading numeric components.
			  Either `NUT_VERSION_FORCED_SEMVER` (if provided by caller or
			  configuration files), or `NUT_VERSION_DEFAULT3` (see above)
			| * `2.8.0`
|`SUFFIX_DESC`		| Optionally populated to construct `DESC` (trimming
			  rc/alpha/beta suffixes from `SUFFIX`, if any)
			| * `""`
			  * `-123+gc0ffee`
|`DESC`			| Constructed from `NUT_VERSION_DEFAULT` for consistency,
			  as `v${NUT_VERSION_DEFAULT3}${SUFFIX_DESC}`, to emulate
			  what `git describe` would have returned, to support NUT
			  SEMVER values saved "as is" into dist tarball files
			| * `""`
			  * `v2.8.0`
			  * `v2.8.3-786+gadfdbe3ab`
|`TAG`			| Constructed as `v${NUT_VERSION_DEFAULT3}${SUFFIX}`
			| * `v2.8.0`
			  * `v2.8.3-rc6`
|=========================================================================

The majority of identified values can be reported for debugging to `stderr`,
currently as a single line (wrapped for readability in the sample below):

----
:; ./tools/gitlog2version.sh
SEMVER=2.8.2;
TRUNK='master';
BASE='e9a48c9afeb4e06c758a3f4215977445c0f64780';
DESC='v2.8.2-2381+g1faa9945d'
=> TAG='v2.8.2' + SUFFIX='-2381+g1faa9945d'
=> VER5='2.8.2.2379.2'
=> VER50='2.8.2.2379.2'
=> DESC50='2.8.2.2379.2-2381+g1faa9945d'
----

.Values reported via `NUT_VERSION_QUERY`
[opts="header",cols="1,3,2a"]
|=========================================================================
|`NUT_VERSION_QUERY`	| Description	| Example (development and release)
|`DESC5`	| Full 5-component version (concatenated with `SUFFIX` for git)
			| * dev: `2.8.2.2379.2-2381+g1faa9945d`
			  * snapshot tarball: `2.8.2.2379.2`
|`DESC50`	| 3-to-5 non-zero component version (concatenated with `SUFFIX`
			  for git)
			| * dev: `2.8.2.2381-2381+g1faa9945d`
			  * snapshot tarball: `2.8.2.1`
|`VER5`		| Full 5-component version
			| * dev: `2.8.2.2379.2`
			  * snapshot tarball: `2.8.2.1.0`
|`VER50`	| 3-to-5 non-zero component version
			| * dev: `2.8.2.2379.2`
			  * release tarball: `2.8.0`
|`DESC5X`, `DESC50X`, `VER5X` and `VER50X`	| Expanded variants of respective
			  reports, with leading zeroes padding up the initial
			  dot-separated numbers to `${NUT_VERSION_EXTRA_WIDTH}`
			  (minimum 6) digits each, allowing for easy scripted
			  alphanumeric comparisons of different NUT releases
			  regardless of digit count in original components.
			| * VER5X with also `NUT_VERSION_EXTRA_WIDTH=9`:
			    `000000002.000000008.000000004.000000910.000000002`
			  * DESC5X with default width (6):
			    `000002.000008.000004.000910.000002-912+g081755da0`
|`SEMVER`	| Exactly three leading numeric components	| * `2.8.2`
|`IS_RELEASE`	| `true` if `SEMVER`==`VER50`, `false` otherwise
			| * dev: `false`
			  * rel: `true`
|`IS_PRERELEASE`	| `true` if `SUFFIX_PRERELEASE` is not empty, `false` otherwise
			| * dev: `false`
			  * rel/RC: `true`
|`TAG`	| GIT: Nearest (annotated by default) tag preceding the `HEAD` in history.
		  DEFAULT: Constructed from `SEMVER`
		| * `v2.8.2`
|`TAG_PRERELEASE`	| GIT: if the `HEAD` itself has a tag matching
		  the `-(rc\|alpha\|beta)[0-9]*` regular expression.
		  DEFAULT: Constructed from `NUT_VERSION_DEFAULT3`
		  and `SUFFIX_PRERELEASE`.
		  Empty for not-pre-releases.
		| * `v2.8.2-rc3`
		  * `""`
|`TRUNK`	| GIT: Branch name used for calculation of current codebase
			  distance from main development.
			  DEFAULT: empty.
			| * `master`
|`SUFFIX`	| GIT: Commit count since the tag and hash of the `HEAD` commit
			  DEFAULT: empty for non-prerelease `NUT_VERSION_DEFAULT`
			  values, or either value of `SUFFIX_PRERELEASE` with a
			  leading dash for `NUT_VERSION_DEFAULT` values without
			  git offset info (e.g. `2.8.3.5-rc6` => `-rc6`), or the
			  whole tail with git and pre-release tag info.
			| * dev: `-2381+g1faa9945d`
			  * RC git: `-2381+g1faa9945d+v2.8.3+rc6`
			  * RC default: `-rc6`
|`SUFFIX_PRERELEASE`	| GIT: Constructed from `TAG_PRERELEASE` replacing any
			  dash with a plus character.
			  DEFAULT: empty unless `NUT_VERSION_DEFAULT` has a
			  suffix matching the `-(rc\|alpha\|beta)[0-9]*`
			  regular expression, or git info followed by
			  the pre-release tag.
              NOTE: No leading dash in this value (unlike `SUFFIX`).
			| * RC git: `v2.8.3+rc6`
			  * RC default: `rc6`
|`BASE`		| GIT: Newest common commit of development `TRUNK` and the `HEAD`
			  commit (their `git merge-base`).
			  DEFAULT: empty.
			| * `e9a48c9afeb4e06c758a3f4215977445c0f64780`
|`URL`	| Clarify the project website URL -- particularly historically
			  frozen snapshots made for releases
			| * dev: `https://www.networkupstools.org/` (default development)
			  * rel: `https://www.networkupstools.org/historic/v2.8.2/index.html`
|`UPDATE_FILE`	| Used in `autogen.sh` and top-level `Makefile.am` to
			  update the `VERSION_DEFAULT` file that goes into "dist"
			  tarballs; prints its contents
			| * `NUT_VERSION_DEFAULT='2.8.2.2379.2-2381+g1faa9945d'`
|`UPDATE_FILE_GIT_RELEASE`	| Used in maintainer rituals (requires git) to
			  update the `VERSION_FORCED` and `VERSION_FORCED_SEMVER`
			  files that go into "dist" tarballs; prints their contents
			| * `NUT_VERSION_FORCED='2.8.2.2878.3-2881+g45029249f+v2.8.3+rc6'`
			  * `NUT_VERSION_FORCED_SEMVER='2.8.3'`
|default	| Report `DESC50`	| * `v2.8.2-2381-g1faa9945d`
|=========================================================================

[NOTE]
======
To facilitate version comparisons of different NUT iterations in scripts,
the "expanded variants" of the two versions can be requested.  This pads each
semver component (but not other numbers) with zeroes to a specified width (by
default 6 digits):

----
:; NUT_VERSION_QUERY=VER5X \
   NUT_VERSION_FORCED=3.14.159.2653.59-2712+gdeadbeef \
   gitlog2version.sh 2>/dev/null
000003.000014.000159.002653.000059
----

If you map this as an e.g. tab-separated list of "expanded" and original
version strings, you can use the shell `sort` command to find the oldest
and newest builds, construct an ordered list for downloads, etc.

Keep in mind that you should not use those zero-padded component numbers
in shell math operations, as they would be considered octal numbers (and
possibly invalid ones, if they contain digits `8` or `9`). You can revert
the operation with envvar toggle `NUT_VERSION_STRIP_LEADING_ZEROES=true`
(note it only impacts the leading dot-separated numbers semver part of the
string, but not any numbers in the suffix):

----
:; NUT_VERSION_QUERY=DESC5 \
   NUT_VERSION_FORCED=3.014.00159.02653.05-002658+gdeadbeef+v01.002.0003 \
   NUT_VERSION_STRIP_LEADING_ZEROES=true \
   gitlog2version.sh 2>/dev/null
3.14.159.2653.5-002658+gdeadbeef+v01.002.0003
----
=====

Using semver-compare.sh
-----------------------

As a result of work on `gitlog2version.sh`, and specifically the next-level
problems of managing the data set of multiple NUT SEMVER strings (sorting,
comparisons, etc.), another helper script was born: the `semver-compare.sh`.

It contains the implementation of "expanded variants" of the versions and
"stripping leading zeroes" used above by the original `gitlog2version.sh`
script, as well as more features used by, for example, the `Makefile.am`
recipes for link:https://github.com/networkupstools/nut-website[nut-website]
which deal with sorted lists of NUT versions for the DDL page rendering
(reports about same device model which originated from different NUT releases).

Common options for scripted actions are (must be mentioned before the action):

`{--width|-w} NUM`::
Pad semver components with leading zeroes to this width (default/min `6`).

`{--min-components} NUM`::
Ensure there are at least so many components - add `.0` in the end if
needed (NUT SEMVER default is `5` for `expand` action).
+
NOTE: Not implemented yet for stripping extra zeroed components from a semver.

Actions which can be repeated on same command line include:

`semver-compare.sh [OPTS] expand "SEMVER"`::
Pad components in semver start of string with leading zeroes up to desired
width.

`semver-compare.sh [OPTS] strip "SEMVER"`::
Strip leading zeroes from components in semver start of string.

`semver-compare.sh [OPTS] --sortable-expand "SEMVER"`::
Print a tab-separated line with expanded variant in first column,
and original in second (so you can `sort` by the first column).

`semver-compare.sh [OPTS] --sortable-strip "SEMVER"`::
Print a tab-separated line with original (presumed expanded) variant in first
column, and stripped in second (so you can `sort` by the first column).

Actions which end the script execution include:

`semver-compare.sh [OPTS] sort [-r] "SEMVER" "SEMVER"...`::
Return sorted (via expansion) list of original semver strings (till end
of args), in their original spelling (with leading zeroes, if present,
not stripped away).

`semver-compare.sh [OPTS] {test|[|[[} "SEMVER1" {-gt|>|-ge|>=|-lt|<|-le|<=|-eq|=|==|-ne|!=|<>} "SEMVER2" {]|]]}`::
Relaxed shell-style syntax to compare two semver strings (via their expanded
variants). Introduced so this script can be just prefixed into existing
(alphanumeric-based) shell comparisons, or newly added with a human-readable
command-line interface.
+
Note that `--min-components` can play a role here (e.g. is `1.2.3` equal
to `1.2.3.0.0`? You can specify whether and how many zeroes can be added
so it would be or not be equal).

NOTE: If you would `sort` expanded semver strings yourself, be sure
to NOT mention the numeric sorting option -- it misbehaves for strings
which do not look like exactly an integer or floating-point number.

For portability and non-regression, the functionality of both scripts is
extensively tested by `tests/nut-driver-enumerator-test.sh` in the NUT code
base.

Variables propagated by configure.ac
------------------------------------

.Values reported via `NUT_VERSION_QUERY`
[opts="header",cols="1,3,2a"]
|=========================================================================
|Variable	| Description	| Example (development and release)
|`PACKAGE_VERSION`	| Argument to `AC_INIT` determined by
			  `NUT_VERSION_QUERY=VER50 gitlog2version.sh`
			| * dev: `2.8.2.695.1`
			  * trunk: `2.8.2.695`
			  * release: `2.8.2`
|`PACKAGE_URL`	| Argument to `AC_INIT` determined by
			  `NUT_VERSION_QUERY=URL gitlog2version.sh`
			| * dev/trunk: `https://www.networkupstools.org/`
			  * release: `https://www.networkupstools.org/historic/v2.8.2/index.html`
|`NUT_WEBSITE_BASE`	| Derived from `PACKAGE_URL` without a trailing slash
			  nor `index.html` (prefixed to documentation file URLs, etc.)
			| * dev/trunk: `https://www.networkupstools.org`
			  * release: `https://www.networkupstools.org/historic/v2.8.2`
|`NUT_SOURCE_GITREV`
			| Determined by `NUT_VERSION_QUERY=DESC50 gitlog2version.sh`
			| * `2.8.2.695.1-696+g0e00f0777`
|`NUT_SOURCE_GITREV_SEMVER`
			| Determined by `NUT_VERSION_QUERY=SEMVER gitlog2version.sh`
			| * `2.8.2`
|`NUT_SOURCE_GITREV_NUMERIC`
			| Determined by `NUT_SOURCE_GITREV` leaving only the numbers,
			  e.g. for PyPI uploads (currently without the total commit count)
			| * `2.8.2.695.1`
|`NUT_SOURCE_GITREV_IS_RELEASE`
			| Determined by `NUT_VERSION_QUERY=IS_RELEASE gitlog2version.sh`
			| * `true`
			  * `false`
|`NUT_SOURCE_GITREV_IS_PRERELEASE`
			| Determined by `NUT_VERSION_QUERY=IS_PRERELEASE gitlog2version.sh`
			| * `true`
			  * `false`
|`NUT_SOURCE_GITREV_DEVREL`
			| String determined by `NUT_SOURCE_GITREV_IS_RELEASE`
			| * `"release"`
			  * `"development iteration"`
|=========================================================================

Variables propagated by nut_version.h
-------------------------------------

.Values encoded via `include/nut_version.h`, generated by `include/Makefile.am`
[opts="header",cols="1,3,2a"]
|=========================================================================
|Variable	| Description	| Example (development and release)
|`#define NUT_VERSION_MACRO "$NUT_VERSION"`
		| Determined by default `gitlog2version.sh` (no `NUT_VERSION_QUERY`)
		  at the moment of latest build, or (as fallback) `PACKAGE_VERSION`
		  set during the last run of `configure` script
		| * `2.8.2.695.1`
|`#define NUT_VERSION_SEMVER_MACRO "$GITREV_SEMVER"`
		| Determined by `NUT_VERSION_QUERY=SEMVER gitlog2version.sh` at the
		  moment of latest build, or (as fallback) `NUT_SOURCE_GITREV_SEMVER`
		  set during the last run of `configure` script
		| * `2.8.2`
|`#define NUT_VERSION_IS_RELEASE <0-or-1>`
		| Determined by `NUT_VERSION_QUERY=IS_RELEASE gitlog2version.sh`
		  (falls back to `false` if that query fails)
		| * `1` if `$GITREV_IS_RELEASE`
		  * `0` otherwise
|`#define NUT_VERSION_IS_PRERELEASE <0-or-1>`
		| Determined by `NUT_VERSION_QUERY=IS_PRERELEASE gitlog2version.sh`
		  (falls back to `false` if that query fails)
		| * `1` if `$GITREV_IS_PRERELEASE`
		  * `0` otherwise
|=========================================================================

Use in C code
-------------

common-nut_version.c
~~~~~~~~~~~~~~~~~~~~

* The `NUT_VERSION_MACRO` is used in `common/common-nut_version.c` and further
  made known to all code base as a static string `UPS_VERSION` linked via
  `libcommon*.la` internal libraries.
* Method `describe_NUT_VERSION_once()` prepares the string which combines the
  `NUT_VERSION_MACRO` with comments that it is either a `release` or a
  `(development iteration after $NUT_VERSION_SEMVER_MACRO)`, based on
  the value of `NUT_VERSION_IS_RELEASE`.
+
It is used from a number of other methods, such as `print_banner_once()`,
  `nut_report_config_flags()`, and so ends up in version reports of programs
  via their `help()`/`usage()` methods.

* Method `suggest_doc_links()` prepares a uniform bit of text for driver and
  tool programs to report in their `help()`/`usage()` methods, to refer to
  their manual page under the `NUT_WEBSITE_BASE`.

Use in resource files and documentation
---------------------------------------

Man pages
~~~~~~~~~

* Manual pages and other documentation consume the `PACKAGE_VERSION`,
  `PACKAGE_VERSION` and `NUT_WEBSITE_BASE` as `asciidoc` attributes
  when rendering HTML/PDF/man document formats.
* The `NUT_WEBSITE_BASE` is also substituted instead of literal
  `https://www.networkupstools.org/*` which follows a `home page:` prefix
  (so that the pages rendered for a release refer to the historic website).

systemd and SMF manifests
~~~~~~~~~~~~~~~~~~~~~~~~~

Service manifests include references to documentation for the tools they wrap,
including published pages under the `NUT_WEBSITE_BASE` for the development or
historic variants of the NUT website.

NUT-Monitor (Python UI) and PyNUTClient
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The `PACKAGE_VERSION` and `NUT_WEBSITE_BASE` are reported in the About dialog.
* Version information is propagated into PyPI packages for the `PyNUTClient`
  module.
