build: change the fallback version suffix to `+git.{sha}`

Seems to be more commonly used than the current `-commit-{sha}`.
Also cleanup/simplify the version handling code and fix the list
of dependencies in the CI scripts.

Change-Id: I4d8826d1012d128883773b7517c44a6abf51fa06
diff --git a/.editorconfig b/.editorconfig
index 624ad9b..f9b3c4d 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -26,3 +26,4 @@
 [*.{yaml,yml}]
 indent_style = space
 indent_size = 2
+trim_trailing_whitespace = true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1ff7602..74f5cd3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,9 +2,13 @@
 on:
   push:
     paths-ignore:
+      - 'Dockerfile'
+      - '.dockerignore'
       - 'docs/**'
-      - '*.md'
+      - '.editorconfig'
+      - '.gitignore'
       - '.mailmap'
+      - '*.md'
   workflow_dispatch:
 
 permissions: {}
diff --git a/.gitignore b/.gitignore
index 6ff803e..dc40a00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,22 +1,8 @@
-# Emacs
+# Backup files
 *~
-\#*\#
-/.emacs.desktop
-/.emacs.desktop.lock
-*.elc
-.\#*
-
-# Visual Studio Code
-.vscode/
-
-# KDevelop
-*.kdev*
-
-# macOS
-.DS_Store
-.AppleDouble
-.LSOverride
-._*
+*.bak
+*.orig
+*.rej
 
 # Waf build system
 /build/
@@ -28,5 +14,21 @@
 __pycache__/
 *.py[cod]
 
+# Emacs
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+.\#*
+
+# Visual Studio Code
+.vscode/
+
+# macOS
+.DS_Store
+.AppleDouble
+.LSOverride
+._*
+
 # Other
 /VERSION.info
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
index d21e972..2bdc040 100755
--- a/.jenkins.d/00-deps.sh
+++ b/.jenkins.d/00-deps.sh
@@ -2,7 +2,8 @@
 set -eo pipefail
 
 APT_PKGS=(
-    build-essential
+    dpkg-dev
+    g++
     libboost-chrono-dev
     libboost-date-time-dev
     libboost-dev
@@ -16,7 +17,7 @@
     libsqlite3-dev
     libssl-dev
     pkg-config
-    python3-minimal
+    python3
 )
 FORMULAE=(boost openssl pkg-config)
 PIP_PKGS=()
diff --git a/COPYING.md b/COPYING.md
index 252444b..496acdb 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -1,32 +1,4 @@
-NLSR is licensed under the terms of the GNU General Public License,
-version 3 or later.
-
-NLSR relies on third-party software, licensed under the following licenses:
-
-- The Boost libraries are licensed under the
-  [Boost Software License 1.0](https://www.boost.org/users/license.html)
-
-- ndn-cxx is licensed under the terms of the
-  [GNU Lesser General Public License version 3](https://github.com/named-data/ndn-cxx/blob/master/COPYING.md)
-
-- ChronoSync is licensed under the terms of the
-  [GNU General Public License version 3](https://github.com/named-data/ChronoSync/blob/master/COPYING.md)
-
-- PSync is licensed under the terms of the
-  [GNU Lesser General Public License version 3](https://github.com/named-data/PSync/blob/master/COPYING.md)
-
-- ndn-svs is licensed under the terms of the
-  [GNU Lesser General Public License v2.1](https://github.com/named-data/ndn-svs/blob/master/COPYING.md)
-
-- The waf build system is licensed under the terms of the
-  [BSD license](https://github.com/named-data/NLSR/blob/master/waf)
-
-The GPL license is provided below in this file.
-For more information, see <https://www.gnu.org/licenses/>
-
---------------------------------------------------------------------------------
-
-### GNU GENERAL PUBLIC LICENSE
+# GNU GENERAL PUBLIC LICENSE
 
 Version 3, 29 June 2007
 
@@ -36,7 +8,7 @@
 Everyone is permitted to copy and distribute verbatim copies of this
 license document, but changing it is not allowed.
 
-### Preamble
+## Preamble
 
 The GNU General Public License is a free, copyleft license for
 software and other kinds of works.
@@ -101,9 +73,9 @@
 The precise terms and conditions for copying, distribution and
 modification follow.
 
-### TERMS AND CONDITIONS
+## TERMS AND CONDITIONS
 
-#### 0. Definitions.
+### 0. Definitions.
 
 "This License" refers to version 3 of the GNU General Public License.
 
@@ -143,7 +115,7 @@
 the interface presents a list of user commands or options, such as a
 menu, a prominent item in the list meets this criterion.
 
-#### 1. Source Code.
+### 1. Source Code.
 
 The "source code" for a work means the preferred form of the work for
 making modifications to it. "Object code" means any non-source form of
@@ -184,7 +156,7 @@
 The Corresponding Source for a work in source code form is that same
 work.
 
-#### 2. Basic Permissions.
+### 2. Basic Permissions.
 
 All rights granted under this License are granted for the term of
 copyright on the Program, and are irrevocable provided the stated
@@ -209,7 +181,7 @@
 conditions stated below. Sublicensing is not allowed; section 10 makes
 it unnecessary.
 
-#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 
 No covered work shall be deemed part of an effective technological
 measure under any applicable law fulfilling obligations under article
@@ -225,7 +197,7 @@
 the work's users, your or third parties' legal rights to forbid
 circumvention of technological measures.
 
-#### 4. Conveying Verbatim Copies.
+### 4. Conveying Verbatim Copies.
 
 You may convey verbatim copies of the Program's source code as you
 receive it, in any medium, provided that you conspicuously and
@@ -238,7 +210,7 @@
 You may charge any price or no price for each copy that you convey,
 and you may offer support or warranty protection for a fee.
 
-#### 5. Conveying Modified Source Versions.
+### 5. Conveying Modified Source Versions.
 
 You may convey a work based on the Program, or the modifications to
 produce it from the Program, in the form of source code under the
@@ -273,7 +245,7 @@
 in an aggregate does not cause this License to apply to the other
 parts of the aggregate.
 
-#### 6. Conveying Non-Source Forms.
+### 6. Conveying Non-Source Forms.
 
 You may convey a covered work in object code form under the terms of
 sections 4 and 5, provided that you also convey the machine-readable
@@ -369,7 +341,7 @@
 source code form), and must require no special password or key for
 unpacking, reading or copying.
 
-#### 7. Additional Terms.
+### 7. Additional Terms.
 
 "Additional permissions" are terms that supplement the terms of this
 License by making exceptions from one or more of its conditions.
@@ -428,7 +400,7 @@
 form of a separately written license, or stated as exceptions; the
 above requirements apply either way.
 
-#### 8. Termination.
+### 8. Termination.
 
 You may not propagate or modify a covered work except as expressly
 provided under this License. Any attempt otherwise to propagate or
@@ -456,7 +428,7 @@
 reinstated, you do not qualify to receive new licenses for the same
 material under section 10.
 
-#### 9. Acceptance Not Required for Having Copies.
+### 9. Acceptance Not Required for Having Copies.
 
 You are not required to accept this License in order to receive or run
 a copy of the Program. Ancillary propagation of a covered work
@@ -467,7 +439,7 @@
 not accept this License. Therefore, by modifying or propagating a
 covered work, you indicate your acceptance of this License to do so.
 
-#### 10. Automatic Licensing of Downstream Recipients.
+### 10. Automatic Licensing of Downstream Recipients.
 
 Each time you convey a covered work, the recipient automatically
 receives a license from the original licensors, to run, modify and
@@ -492,7 +464,7 @@
 any patent claim is infringed by making, using, selling, offering for
 sale, or importing the Program or any portion of it.
 
-#### 11. Patents.
+### 11. Patents.
 
 A "contributor" is a copyright holder who authorizes use under this
 License of the Program or a work on which the Program is based. The
@@ -561,7 +533,7 @@
 any implied license or other defenses to infringement that may
 otherwise be available to you under applicable patent law.
 
-#### 12. No Surrender of Others' Freedom.
+### 12. No Surrender of Others' Freedom.
 
 If conditions are imposed on you (whether by court order, agreement or
 otherwise) that contradict the conditions of this License, they do not
@@ -574,7 +546,7 @@
 satisfy both those terms and this License would be to refrain entirely
 from conveying the Program.
 
-#### 13. Use with the GNU Affero General Public License.
+### 13. Use with the GNU Affero General Public License.
 
 Notwithstanding any other provision of this License, you have
 permission to link or combine any covered work with a work licensed
@@ -585,7 +557,7 @@
 section 13, concerning interaction through a network will apply to the
 combination as such.
 
-#### 14. Revised Versions of this License.
+### 14. Revised Versions of this License.
 
 The Free Software Foundation may publish revised and/or new versions
 of the GNU General Public License from time to time. Such new versions
@@ -611,7 +583,7 @@
 author or copyright holder as a result of your choosing to follow a
 later version.
 
-#### 15. Disclaimer of Warranty.
+### 15. Disclaimer of Warranty.
 
 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
@@ -623,7 +595,7 @@
 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
 CORRECTION.
 
-#### 16. Limitation of Liability.
+### 16. Limitation of Liability.
 
 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
@@ -635,7 +607,7 @@
 TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
 PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
-#### 17. Interpretation of Sections 15 and 16.
+### 17. Interpretation of Sections 15 and 16.
 
 If the disclaimer of warranty and limitation of liability provided
 above cannot be given local legal effect according to their terms,
@@ -646,7 +618,7 @@
 
 END OF TERMS AND CONDITIONS
 
-### How to Apply These Terms to Your New Programs
+## How to Apply These Terms to Your New Programs
 
 If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
diff --git a/README.md b/README.md
index ccdf706..bd92d52 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,12 @@
 # NLSR: Named Data Link State Routing Protocol
 
+![Latest version](https://img.shields.io/github/v/tag/named-data/NLSR?label=Latest%20version)
+![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
 [![CI](https://github.com/named-data/NLSR/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/NLSR/actions/workflows/ci.yml)
 [![Docs](https://github.com/named-data/NLSR/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/NLSR/actions/workflows/docs.yml)
-![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
-![Latest version](https://img.shields.io/github/v/tag/named-data/NLSR?label=Latest%20version)
 
-> For more extensive documentation, please visit the [NLSR homepage](https://docs.named-data.net/NLSR/current/).
+> [!TIP]
+> For more extensive documentation, visit the [NLSR homepage](https://docs.named-data.net/NLSR/current/).
 
 ## Overview
 
@@ -49,3 +50,7 @@
 
 NLSR is free software distributed under the GNU General Public License version 3.
 See [`COPYING.md`](COPYING.md) for details.
+
+NLSR contains third-party software, licensed under the following licenses:
+
+- The *waf* build system is licensed under the [3-clause BSD license](waf)
diff --git a/wscript b/wscript
index 50c8cf8..74dcee0 100644
--- a/wscript
+++ b/wscript
@@ -219,43 +219,43 @@
     Context.g_module.VERSION_SPLIT = VERSION_BASE.split('.')
 
     # first, try to get a version string from git
-    gotVersionFromGit = False
+    version_from_git = ''
     try:
-        cmd = ['git', 'describe', '--always', '--match', f'{GIT_TAG_PREFIX}*']
-        out = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip()
-        if out:
-            gotVersionFromGit = True
-            if out.startswith(GIT_TAG_PREFIX):
-                Context.g_module.VERSION = out.lstrip(GIT_TAG_PREFIX)
+        cmd = ['git', 'describe', '--abbrev=8', '--always', '--match', f'{GIT_TAG_PREFIX}*']
+        version_from_git = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip()
+        if version_from_git:
+            if GIT_TAG_PREFIX and version_from_git.startswith(GIT_TAG_PREFIX):
+                Context.g_module.VERSION = version_from_git[len(GIT_TAG_PREFIX):]
+            elif not GIT_TAG_PREFIX and ('.' in version_from_git or '-' in version_from_git):
+                Context.g_module.VERSION = version_from_git
             else:
-                # no tags matched
-                Context.g_module.VERSION = f'{VERSION_BASE}-commit-{out}'
+                # no tags matched (or we are in a shallow clone)
+                Context.g_module.VERSION = f'{VERSION_BASE}+git.{version_from_git}'
     except (OSError, subprocess.SubprocessError):
         pass
 
-    versionFile = ctx.path.find_node('VERSION.info')
-    if not gotVersionFromGit and versionFile is not None:
+    # fallback to the VERSION.info file, if it exists and is not empty
+    version_from_file = ''
+    version_file = ctx.path.find_node('VERSION.info')
+    if version_file is not None:
         try:
-            Context.g_module.VERSION = versionFile.read()
-            return
-        except EnvironmentError:
-            pass
+            version_from_file = version_file.read().strip()
+        except OSError as e:
+            Logs.warn(f'{e.filename} exists but is not readable ({e.strerror})')
+    if version_from_file and not version_from_git:
+        Context.g_module.VERSION = version_from_file
+        return
 
-    # version was obtained from git, update VERSION file if necessary
-    if versionFile is not None:
-        try:
-            if versionFile.read() == Context.g_module.VERSION:
-                # already up-to-date
-                return
-        except EnvironmentError as e:
-            Logs.warn(f'{versionFile} exists but is not readable ({e.strerror})')
-    else:
-        versionFile = ctx.path.make_node('VERSION.info')
-
+    # update VERSION.info if necessary
+    if version_from_file == Context.g_module.VERSION:
+        # already up-to-date
+        return
+    if version_file is None:
+        version_file = ctx.path.make_node('VERSION.info')
     try:
-        versionFile.write(Context.g_module.VERSION)
-    except EnvironmentError as e:
-        Logs.warn(f'{versionFile} is not writable ({e.strerror})')
+        version_file.write(Context.g_module.VERSION)
+    except OSError as e:
+        Logs.warn(f'{e.filename} is not writable ({e.strerror})')
 
 def dist(ctx):
     ctx.algo = 'tar.xz'