diff --git a/INSTALL.nut.adoc b/INSTALL.nut.adoc index c546d49136..20c8e59ec0 100644 --- a/INSTALL.nut.adoc +++ b/INSTALL.nut.adoc @@ -279,13 +279,19 @@ for developers iterating on some features. changed. On many systems it suffices to add e.g. `/usr/lib/ccache` early in `PATH` and populate it with symlinks to e.g. `/usr/bin/ccache` using various compiler program names. -* If you are a developer iterating with debug builds on different branches, - `export CI_AUTOGEN_STABLE_VERSION=true` can additionally ensure that the - `AC_INIT` in the generated `configure` script would not follow NUT SEMVER - but use a shorter and temporally stable version string. This helps on some - systems where enabling debug options embeds all macros into compiled objects, - so an ever-changing `PACKAGE_VERSION` in `config.h` which does follow NUT - SEMVER prevents `ccache` direct mode (because each build is deemed unique). + The full Git-derived NUT version, which changes with every commit, is not + stored in the `include/config.h` file (included by all sources) but only + in `include/nut_version.h` (included by a couple of source files), so after + a new commit or in a fresh checkout, only those few objects get recompiled. + This matters especially for debug builds with options like `-g3` which + embed all macro definitions into compiled objects, so `ccache` can not + fall back to its preprocessor mode to find a match for a changed macro. + If several Git work trees or checkout directories share one cache, set + `CCACHE_BASEDIR` to a common parent directory so that absolute paths in + compiler command lines do not prevent cache hits. +* When you iterate code development, `make NUT_VERSION_H_GENERATED=true` + can skip regeneration of `include/nut_version.h` (at a cost of a less + precise version reported by the built programs). * Using `export DO_USE_NUTCI_CACHE=yes` (and derived environment variables like `DO_USE_AUTOCONF_CACHE` or `DO_USE_NIT_TESTCERT_CACHE`) can be used to speed up re-builds with `ci_build.sh` and re-runs of NUT Integration diff --git a/NEWS.adoc b/NEWS.adoc index 67077f8612..db66a718a5 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -1048,6 +1048,13 @@ https://github.com/networkupstools/nut/milestone/13 with both a current and an old (7.1, as on CentOS 7) version of the `aspell-en` dictionary. Local builds keep the default of `configure --enable-spellcheck=auto`. [PR #3752] + * The `include/config.h` file no longer carries the full Git-derived NUT + version (which changes with every commit), only the base semantic + version (e.g. `2.8.5` for a release, or `2.8.5.1` for any development + iteration after it), so `ccache` and similar build caches can re-use + compiled objects across commits and fresh CI checkouts. The full + version is still provided by `include/nut_version.h` and in the + substituted `@PACKAGE_VERSION@` values. [PR #3759, follow-up to PR #3754] * The `make shellcheck` (and `make check-scripts-syntax`) recipe can now check the POSIX shell scripts with each interpreter listed in the `SHELL_PROGS` environment variable (default is still the system diff --git a/UPGRADING.adoc b/UPGRADING.adoc index 15fa29dece..b68421c75b 100644 --- a/UPGRADING.adoc +++ b/UPGRADING.adoc @@ -33,6 +33,18 @@ Changes from 2.8.5 to 2.8.6 - PLANNED: Keep track of any further API clean-up? +- The `PACKAGE_VERSION` and `PACKAGE_STRING` macros in the generated + `include/config.h` now only carry the base semantic version (e.g. `2.8.5` + for a release, or `2.8.5.1` for any development iteration after it) rather + than the full Git-derived version (e.g. `2.8.5.1466.13`), and the + `PACKAGE` and `VERSION` macros are no longer defined there, so that build + caches remain valid across commits. The `./configure --version` output + also reports this shortened version. Code which needs the full version + should use `NUT_VERSION_MACRO` from the generated `include/nut_version.h`. + The `@PACKAGE_VERSION@` and `@VERSION@` values substituted into Makefiles, + `*.pc` files, packaging recipes and tarball names are not changed. + [PR #3754 follow-up] + - The Perl `UPS::Nut` module now decodes NUT quoting and backslash escapes in query/list values and `nutauth.conf`, including include paths. Remove manual decoding of these returned values and pass literal credentials diff --git a/appveyor.yml b/appveyor.yml index 8ae93250fa..74097fdee3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -35,9 +35,6 @@ environment: # ccache max_size is capped below (see install steps) to leave a margin # for the other entries (pacman packages ~100MB, nut-win-deps, nut-ci): APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -mx=0 - # Keep config.h stable across PRs, so ccache can reuse -g3 objects - # (see ci_build.sh for details): - CI_AUTOGEN_STABLE_VERSION: true CCACHE_DIR: /home/appveyor/.ccache DO_CLEAN_NUTCI_CACHE: no DO_USE_NUTCI_CACHE: yes diff --git a/ci_build.sh b/ci_build.sh index 360706871f..1e4cd0b7d3 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -1136,32 +1136,11 @@ do_autogen_get_CONFIGURE_SCRIPT() { # older system) we have to remove it when we already have the script. # This matches the use-case of distro-building from release tarballs that # include all needed pre-generated files to rely less on OS facilities. - ( - # Optionally drop the PR-specific last component of the version - # (e.g. 2.8.5.1466.13 => 2.8.5.1466) which AC_INIT puts into - # config.h as PACKAGE_VERSION. The ccache direct mode hashes all - # included headers, so a version change misses for nearly every - # file and defeats ccache across pull requests. Only autogen.sh gets - # this setting, so `make` still generates nut_version.h (and the - # UPS_VERSION reported by programs) from actual Git metadata. - if [ x"${CI_AUTOGEN_STABLE_VERSION-}" = xtrue ] && [ -z "${NUT_VERSION_FORCED-}" ] ; then - _NUT_VERSION_STABLE="`NUT_VERSION_QUERY=VER50 ./tools/gitlog2version.sh 2>/dev/null`" || _NUT_VERSION_STABLE="" - case "${_NUT_VERSION_STABLE}" in - *.*.*.*.*) _NUT_VERSION_STABLE="${_NUT_VERSION_STABLE%.*}" ;; - esac - if [ -n "${_NUT_VERSION_STABLE}" ] ; then - echo "INFO: CI_AUTOGEN_STABLE_VERSION: using NUT_VERSION_FORCED='${_NUT_VERSION_STABLE}' for autogen.sh" >&2 - NUT_VERSION_FORCED="${_NUT_VERSION_STABLE}" - export NUT_VERSION_FORCED - fi - fi - - if [ "$CI_OS_NAME" = "windows" ] ; then - $CI_TIME ./autogen.sh || true - else - $CI_TIME ./autogen.sh ### 2>/dev/null - fi - ) || exit + if [ "$CI_OS_NAME" = "windows" ] ; then + $CI_TIME ./autogen.sh || true + else + $CI_TIME ./autogen.sh ### 2>/dev/null + fi || exit fi # Retain the full path to configure script file diff --git a/configure.ac b/configure.ac index 317db1f480..a4f3a6c632 100644 --- a/configure.ac +++ b/configure.ac @@ -23,12 +23,28 @@ dnl See https://github.com/networkupstools/nut/issues/1949 for details. dnl Oddly, autoconf-2.69 on CentOS 7 both complains that AC INIT argument dnl is not a literal, and does contain expected values in the generated dnl script and include/config.h. A "pure" m4 solution would be quieter. +dnl NOTE: AC_INIT gets the base SEMVER for releases (e.g. "2.8.5"), and a +dnl nominal "SEMVER.1" for any development iteration after it (e.g. "2.8.5.1"), +dnl which does not change between releases. It ends up in include/config.h +dnl as PACKAGE_VERSION and PACKAGE_STRING macros, and every source file +dnl includes config.h, so with +dnl the full git-derived version there every new commit would invalidate all +dnl compiled objects in ccache (direct mode) or similar build caches. The +dnl full version (VER50, e.g. "2.8.5.1466.13") is assigned to the shell +dnl variables right below, so all AC_SUBST'ed @PACKAGE_VERSION@ and friends +dnl (Makefiles, *.pc files, packaging recipes, tarball names) are not changed. +dnl C code should use NUT_VERSION_MACRO from include/nut_version.h which is +dnl generated by make and only consumed by a couple of source files. AC_INIT([nut], - m4_esyscmd_s([NUT_VERSION_QUERY=VER50 "`dirname \"$0\"`/tools/gitlog2version.sh" 2>/dev/null]), + m4_esyscmd_s([NUT_VERSION_QUERY=SEMVER_ACINIT "`dirname \"$0\"`/tools/gitlog2version.sh" 2>/dev/null]), [https://github.com/networkupstools/nut/issues],[nut], m4_esyscmd_s([NUT_VERSION_QUERY=URL "`dirname \"$0\"`/tools/gitlog2version.sh" 2>/dev/null])) dnl See docs/maintainer-guide.txt about releases - updating the version dnl above is a small part of the consistent ritual! +NUT_ACINIT_VERSION="${PACKAGE_VERSION}" +PACKAGE_VERSION='m4_esyscmd_s([NUT_VERSION_QUERY=VER50 "`dirname \"$0\"`/tools/gitlog2version.sh" 2>/dev/null])' +test -n "${PACKAGE_VERSION}" || PACKAGE_VERSION="${NUT_ACINIT_VERSION}" +PACKAGE_STRING="${PACKAGE_NAME} ${PACKAGE_VERSION}" dnl Detect usable grep and egrep as soon as possible, to let called scripts dnl use them. Unfortunately, init must happen before macros that output text, @@ -218,7 +234,11 @@ AC_SUBST([NUT_CONFIG_LDFLAGS]) NUT_STASH_WARNINGS AC_CONFIG_HEADERS([include/config.h]) AC_PREFIX_DEFAULT(/usr/local/ups) -AM_INIT_AUTOMAKE([subdir-objects tar-pax]) +dnl Do not define PACKAGE and VERSION macros in config.h (not used by code); +dnl the VERSION substitution would be the AC_INIT SEMVER, so (re-)set it to +dnl the full version for Makefile purposes (distdir, tarball names...) +AM_INIT_AUTOMAKE([subdir-objects tar-pax no-define]) +VERSION="${PACKAGE_VERSION}" AS_CASE([${target_os}], [*mingw*], [AS_CASE([${CFLAGS-}${CXXFLAGS-}], diff --git a/docs/developers.txt b/docs/developers.txt index 7042026436..d0b87fe515 100644 --- a/docs/developers.txt +++ b/docs/developers.txt @@ -336,6 +336,16 @@ build agent preparation,NUTCI_farm_agents]. See also "Repetitive build/test optimizations" in `INSTALL.nut.adoc` file for suggestions specific to this area. +The full Git-derived NUT version (e.g. `2.8.5.1466.13`) changes with every +commit, so it is kept out of `include/config.h` (included by all sources) +to let `ccache` re-use objects: the `PACKAGE_VERSION` and `PACKAGE_STRING` +macros there only carry the base semantic version (e.g. `2.8.5`, or +`2.8.5.1` for any development iteration after that release). Please +do not use these macros in new C code; the full version is provided by +`NUT_VERSION_MACRO` in the generated `include/nut_version.h` file (exposed +to programs by the `UPS_VERSION` string in common code), and that header +should not be included by more source files than necessary. + Integrated Development Environments (IDEs) and debugging NUT ------------------------------------------------------------ diff --git a/docs/nut-versioning.adoc b/docs/nut-versioning.adoc index e632ecd6f6..4d7239e7a3 100644 --- a/docs/nut-versioning.adoc +++ b/docs/nut-versioning.adoc @@ -322,6 +322,13 @@ DESC='v2.8.2-2381+g1faa9945d' * DESC5X with default width (6): `000002.000008.000004.000910.000002-912+g081755da0` |`SEMVER` | Exactly three leading numeric components | * `2.8.2` +|`SEMVER_ACINIT` | `SEMVER` for releases, or a nominal `SEMVER.1` for any + development iteration after that release (for pre-releases, + the triplet of `VER50` is used, unless forced otherwise). + Used for `AC_INIT` (so ends up in `config.h` macros), and + does not change between releases, to benefit build caches. + | * dev: `2.8.2.1` + * rel: `2.8.2` |`IS_RELEASE` | `true` if `SEMVER`==`VER50`, `false` otherwise | * dev: `false` * rel: `true` diff --git a/docs/nut.dict b/docs/nut.dict index b8ad7835e8..918c2891ba 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,9 +1,10 @@ -personal_ws-1.1 en 3916 utf-8 +personal_ws-1.1 en 3917 utf-8 AAC AAS ABI ACFAIL ACFREQ +ACINIT ACK ACM ACPI diff --git a/tests/nut-driver-enumerator-test.sh b/tests/nut-driver-enumerator-test.sh index dbe9a0e83f..54ebd7bf79 100755 --- a/tests/nut-driver-enumerator-test.sh +++ b/tests/nut-driver-enumerator-test.sh @@ -528,7 +528,7 @@ testcase_gitlog2version() { TRUNK='origin/master' BASE='adfdbe3aba19e157010075c42fba7c3174e9baa7' \ run_testcase_generic callG2V \ "Testing that parsing from a NUT_VERSION_FORCED string for a known git checkout returns same results, for a release candidate" 0 \ -"SEMVER=2.8.4; TRUNK=''; BASE=''; DESC='v2.8.3-786+gadfdbe3ab' => TAG='v2.8.3' + SUFFIX='-786+gadfdbe3ab+v2.8.4+rc3' => VER5='2.8.3.786.0' => DESC5='2.8.3.786.0-786+gadfdbe3ab+v2.8.4+rc3' => VER50='2.8.3.786' => DESC50='2.8.3.786-786+gadfdbe3ab+v2.8.4+rc3' +"SEMVER=2.8.4; SEMVER_ACINIT=2.8.3.1; TRUNK=''; BASE=''; DESC='v2.8.3-786+gadfdbe3ab' => TAG='v2.8.3' + SUFFIX='-786+gadfdbe3ab+v2.8.4+rc3' => VER5='2.8.3.786.0' => DESC5='2.8.3.786.0-786+gadfdbe3ab+v2.8.4+rc3' => VER50='2.8.3.786' => DESC50='2.8.3.786-786+gadfdbe3ab+v2.8.4+rc3' 2.8.3.786-786+gadfdbe3ab+v2.8.4+rc3" # Taken from `git checkout v2.8.4` (emptied TRUNK and BASE): @@ -536,14 +536,14 @@ testcase_gitlog2version() { TRUNK='origin/master' BASE='541c2ecf0b2ec33dadb9f40b16acbe39042bd103' \ run_testcase_generic callG2V \ "Testing that parsing from a NUT_VERSION_FORCED string for a known git checkout returns same results, for a release (tag)" 0 \ -"SEMVER=2.8.4; TRUNK=''; BASE=''; DESC='v2.8.4' => TAG='v2.8.4' + SUFFIX='' => VER5='2.8.4.0.0' => DESC5='2.8.4.0.0' => VER50='2.8.4' => DESC50='2.8.4' +"SEMVER=2.8.4; SEMVER_ACINIT=2.8.4; TRUNK=''; BASE=''; DESC='v2.8.4' => TAG='v2.8.4' + SUFFIX='' => VER5='2.8.4.0.0' => DESC5='2.8.4.0.0' => VER50='2.8.4' => DESC50='2.8.4' 2.8.4" NUT_VERSION_QUERY=DESC5X \ NUT_VERSION_FORCED=3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1 \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a release candidate, with extra fields" 0 \ -"SEMVER=3.14.160; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef+v3.14.160+rc1' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' +"SEMVER=3.14.160; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef+v3.14.160+rc1' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' 000003.000014.000159.002653.000059-2712+gdeadbeef+v3.14.160+rc1" NUT_VERSION_QUERY=VER5X \ @@ -551,7 +551,7 @@ testcase_gitlog2version() { NUT_VERSION_EXTRA_WIDTH=9 \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a release candidate, just the numeric part" 0 \ -"SEMVER=3.14.160; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef+v3.14.160+rc1' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' +"SEMVER=3.14.160; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef+v3.14.160+rc1' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef+v3.14.160+rc1' 000000003.000000014.000000159.000002653.000000059" # Reset NUT_VERSION_EXTRA_WIDTH for ksh out there @@ -560,7 +560,7 @@ testcase_gitlog2version() { NUT_VERSION_FORCED=3.14.159.2653.59-2712+gdeadbeef \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a dev iteration, with extra fields" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef' 000003.000014.000159.002653.000059-2712+gdeadbeef" NUT_VERSION_QUERY=VER5X \ @@ -568,7 +568,7 @@ testcase_gitlog2version() { NUT_VERSION_EXTRA_WIDTH=8 \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a dev iteration, just the numeric part, wider numbers" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef' 00000003.00000014.00000159.00002653.00000059" # Reset NUT_VERSION_EXTRA_WIDTH for ksh out there @@ -577,14 +577,14 @@ testcase_gitlog2version() { NUT_VERSION_FORCED=3.14.159.2653 \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a master merge increment, just the numeric part (requiring at least 5 numeric components)" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159' => TAG='v3.14.159' + SUFFIX='' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0' => VER50='3.14.159.2653' => DESC50='3.14.159.2653' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159' => TAG='v3.14.159' + SUFFIX='' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0' => VER50='3.14.159.2653' => DESC50='3.14.159.2653' 000003.000014.000159.002653.000000" NUT_VERSION_QUERY=VER50X \ NUT_VERSION_FORCED=3.14.159.2653 \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, for a master merge increment, just the numeric part (dropping trailing zero numeric components)" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159' => TAG='v3.14.159' + SUFFIX='' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0' => VER50='3.14.159.2653' => DESC50='3.14.159.2653' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159' => TAG='v3.14.159' + SUFFIX='' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0' => VER50='3.14.159.2653' => DESC50='3.14.159.2653' 000003.000014.000159.002653" # Note that DESC must be either a tag as is, @@ -594,14 +594,14 @@ testcase_gitlog2version() { NUT_VERSION_FORCED=3.14.159+gdeadbeef \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, with a trailing gHASH but no commit count" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-0+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-0+gdeadbeef' => VER5='3.14.159.0.0' => DESC5='3.14.159.0.0-0+gdeadbeef' => VER50='3.14.159' => DESC50='3.14.159-0+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-0+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-0+gdeadbeef' => VER5='3.14.159.0.0' => DESC5='3.14.159.0.0-0+gdeadbeef' => VER50='3.14.159' => DESC50='3.14.159-0+gdeadbeef' 3.14.159-0+gdeadbeef" # ...auto-account the offset since tag correctly: NUT_VERSION_FORCED=3.14.159.2653+gdeadbeef \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, with a trailing gHASH but no commit count" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-2653+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2653+gdeadbeef' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0-2653+gdeadbeef' => VER50='3.14.159.2653' => DESC50='3.14.159.2653-2653+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2653+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2653+gdeadbeef' => VER5='3.14.159.2653.0' => DESC5='3.14.159.2653.0-2653+gdeadbeef' => VER50='3.14.159.2653' => DESC50='3.14.159.2653-2653+gdeadbeef' 3.14.159.2653-2653+gdeadbeef" # ...auto-account the offset since tag correctly @@ -609,7 +609,7 @@ testcase_gitlog2version() { NUT_VERSION_FORCED=3.14.159.2653.5+gdeadbeef \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, with a trailing gHASH but no commit count" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-2658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2658+gdeadbeef' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-2658+gdeadbeef' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-2658+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2658+gdeadbeef' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-2658+gdeadbeef' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-2658+gdeadbeef' 3.14.159.2653.5-2658+gdeadbeef" NUT_VERSION_QUERY=DESC5X \ @@ -617,7 +617,7 @@ testcase_gitlog2version() { NUT_VERSION_STRIP_LEADING_ZEROES=true \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, with leading zeroes, also a trailing gHASH but no commit count" 0 \ -"SEMVER=3.14.159; TRUNK=''; BASE=''; DESC='v3.14.159-2658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2658+gdeadbeef' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-2658+gdeadbeef' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-2658+gdeadbeef' +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2658+gdeadbeef' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-2658+gdeadbeef' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-2658+gdeadbeef' 000003.000014.000159.002653.000005-2658+gdeadbeef" # Note here SEMVER is taken from the future version that the RC is for @@ -626,8 +626,54 @@ testcase_gitlog2version() { NUT_VERSION_STRIP_LEADING_ZEROES=true \ run_testcase_generic callG2V \ "Complex (forced) NUT version expanded for alphanumeric comparisons, with leading zeroes, also in the commit count and RC suffix" 0 \ -"SEMVER=4.5.6; TRUNK=''; BASE=''; DESC='v3.14.159-002658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-002658+gdeadbeef+v04.005.0006+rc001' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-002658+gdeadbeef+v04.005.0006+rc001' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-002658+gdeadbeef+v04.005.0006+rc001' +"SEMVER=4.5.6; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-002658+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-002658+gdeadbeef+v04.005.0006+rc001' => VER5='3.14.159.2653.5' => DESC5='3.14.159.2653.5-002658+gdeadbeef+v04.005.0006+rc001' => VER50='3.14.159.2653.5' => DESC50='3.14.159.2653.5-002658+gdeadbeef+v04.005.0006+rc001' 000003.000014.000159.002653.000005-002658+gdeadbeef+v04.005.0006+rc001" + + # SEMVER_ACINIT (for AC_INIT and so config.h) is the SEMVER for + # releases, and a nominal "triplet.1" for development iterations + # Reset NUT_VERSION_STRIP_LEADING_ZEROES for ksh out there + NUT_VERSION_STRIP_LEADING_ZEROES='' \ + NUT_VERSION_QUERY=SEMVER_ACINIT \ + NUT_VERSION_FORCED=2.8.4 \ + run_testcase_generic callG2V \ + "Stable NUT version for AC_INIT, for a release (tag)" 0 \ +"SEMVER=2.8.4; SEMVER_ACINIT=2.8.4; TRUNK=''; BASE=''; DESC='v2.8.4' => TAG='v2.8.4' + SUFFIX='' => VER5='2.8.4.0.0' => DESC5='2.8.4.0.0' => VER50='2.8.4' => DESC50='2.8.4' +2.8.4" + + # NOTE: VER50 retains trailing .0 from the input, but SEMVER_ACINIT + # should not become 2.8.4.1 for what is still a release (zero commits + # after tag) + NUT_VERSION_STRIP_LEADING_ZEROES='' \ + NUT_VERSION_QUERY=SEMVER_ACINIT \ + NUT_VERSION_FORCED=2.8.4.0 \ + run_testcase_generic callG2V \ + "Stable NUT version for AC_INIT, for a release (tag)" 0 \ +"SEMVER=2.8.4; SEMVER_ACINIT=2.8.4; TRUNK=''; BASE=''; DESC='v2.8.4' => TAG='v2.8.4' + SUFFIX='' => VER5='2.8.4.0.0' => DESC5='2.8.4.0.0' => VER50='2.8.4.0' => DESC50='2.8.4.0' +2.8.4" + + NUT_VERSION_QUERY=SEMVER_ACINIT \ + NUT_VERSION_FORCED=3.14.159.2653.59-2712+gdeadbeef \ + run_testcase_generic callG2V \ + "Stable NUT version for AC_INIT, for a dev iteration" 0 \ +"SEMVER=3.14.159; SEMVER_ACINIT=3.14.159.1; TRUNK=''; BASE=''; DESC='v3.14.159-2712+gdeadbeef' => TAG='v3.14.159' + SUFFIX='-2712+gdeadbeef' => VER5='3.14.159.2653.59' => DESC5='3.14.159.2653.59-2712+gdeadbeef' => VER50='3.14.159.2653.59' => DESC50='3.14.159.2653.59-2712+gdeadbeef' +3.14.159.1" + + # Like NUT_VERSION_DEFAULT between releases: no second ".1" suffix + NUT_VERSION_QUERY=SEMVER_ACINIT \ + NUT_VERSION_FORCED=2.8.5.1 \ + run_testcase_generic callG2V \ + "Stable NUT version for AC_INIT, for a 4-component default version" 0 \ +"SEMVER=2.8.5; SEMVER_ACINIT=2.8.5.1; TRUNK=''; BASE=''; DESC='v2.8.5' => TAG='v2.8.5' + SUFFIX='' => VER5='2.8.5.1.0' => DESC5='2.8.5.1.0' => VER50='2.8.5.1' => DESC50='2.8.5.1' +2.8.5.1" + + # For a release candidate, SEMVER is the upcoming release, but + # SEMVER_ACINIT is a dev iteration after the preceding release + NUT_VERSION_QUERY=SEMVER_ACINIT \ + NUT_VERSION_FORCED=2.8.3.786-786+gadfdbe3ab+v2.8.4+rc3 \ + run_testcase_generic callG2V \ + "Stable NUT version for AC_INIT, for a release candidate" 0 \ +"SEMVER=2.8.4; SEMVER_ACINIT=2.8.3.1; TRUNK=''; BASE=''; DESC='v2.8.3-786+gadfdbe3ab' => TAG='v2.8.3' + SUFFIX='-786+gadfdbe3ab+v2.8.4+rc3' => VER5='2.8.3.786.0' => DESC5='2.8.3.786.0-786+gadfdbe3ab+v2.8.4+rc3' => VER50='2.8.3.786' => DESC50='2.8.3.786-786+gadfdbe3ab+v2.8.4+rc3' +2.8.3.1" } testcase_semver_compare() { diff --git a/tools/gitlog2version.sh b/tools/gitlog2version.sh index f15acda867..d89c2246a9 100755 --- a/tools/gitlog2version.sh +++ b/tools/gitlog2version.sh @@ -499,9 +499,36 @@ getver_default() { fi } +getver_acinit() { + # Temporally stable version for AC_INIT (ends up in config.h macros): + # exactly SEMVER for releases, and by legacy convention a nominal + # "triplet.1" for any development iteration after that release. + # Note that for pre-release tagged commits SEMVER is the upcoming + # release, while the code is still a development iteration after the + # previous one (unless the caller forced a SEMVER), so take the + # triplet from VER50 in that case. Starting from a triplet ensures + # we do not add a second ".1" to 4-component NUT_VERSION_DEFAULT. + if [ x"${SEMVER}" = x"${VER50}" ] ; then + SEMVER_ACINIT="${SEMVER}" + elif [ -n "${SUFFIX_PRERELEASE}" ] && [ -z "${NUT_VERSION_FORCED_SEMVER-}" ] ; then + SEMVER_ACINIT="`echo \"${VER50}\" | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[^0-9].*$/\1/'`.1" + else + # Check if the version forced from input is like `X.Y.Z.0(.0...)` + # (still a release, zero commits after tag), and do not turn it + # into `X.Y.Z.1` needlessly. + _VER50="`echo \"${VER50}\" | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)\(\.00*\)*$/\1/'`" + if [ x"${SEMVER}" = x"${_VER50}" ] ; then + SEMVER_ACINIT="${SEMVER}" + else + SEMVER_ACINIT="${SEMVER}.1" + fi + unset _VER50 + fi +} + report_debug() { # Debug - echo "SEMVER=${SEMVER}; TRUNK='${NUT_VERSION_GIT_TRUNK-}'; BASE='${BASE}'; DESC='${DESC}' => TAG='${TAG}' + SUFFIX='${SUFFIX}' => VER5='${VER5}' => DESC5='${DESC5}' => VER50='${VER50}' => DESC50='${DESC50}'" >&2 + echo "SEMVER=${SEMVER}; SEMVER_ACINIT=${SEMVER_ACINIT}; TRUNK='${NUT_VERSION_GIT_TRUNK-}'; BASE='${BASE}'; DESC='${DESC}' => TAG='${TAG}' + SUFFIX='${SUFFIX}' => VER5='${VER5}' => DESC5='${DESC5}' => VER50='${VER50}' => DESC50='${DESC50}'" >&2 } report_output() { @@ -515,6 +542,7 @@ report_output() { "VER50") echo "${VER50}" ;; "VER50x"|"VER50X") "${SEMVER_COMPARE}" --expand "${VER50}" ;; "SEMVER") echo "${SEMVER}" ;; + "SEMVER_ACINIT") echo "${SEMVER_ACINIT}" ;; "IS_RELEASE") [ x"${SEMVER}" = x"${VER50}" ] && echo true || echo false ;; "IS_PRERELEASE") [ x"${SUFFIX_PRERELEASE}" != x ] && echo true || echo false ;; "TAG") echo "${TAG}" ;; @@ -639,6 +667,7 @@ if [ x"$DESC" = x ]; then fi fi +getver_acinit report_debug report_output