Repository: NordicHPC/sonar (language: python)

Issue:
`sonar help` should print version and build date
I think it will be helpful for sonar to be able to self-identify.


Discussion / hints:
Yes absolutely. This looks like something I should be able to solve. Taking it.
And we are few months later ... reminding myself of this issue.
Poaching since we want this for the new "release procedures".

Version is trivially gotten from Cargo.  The build time we can get with https://github.com/AlephAlpha/build-time which is MIT license and we can crib the code we need to avoid taking a dependency.
The build date turns out to be a boondoggle (proc macros + lots of dependencies) and I don't want to deal with it now; the version number is 90% of it anyway.
I looked into whether it would be meaningful to make use of the facility in Cargo that allows a prerelease tag, eg, 0.13.0-7, to signify time passing on the main branch (v0.13) when 0.12 is the latest release branch.  It didn't seem worth the bother at this time and it doesn't really solve any problems.  Data in the production data stream should really never be produced by prerelease versions.

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 3baeed5..d110324 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
 
 [[package]]
 name = "sonar"
-version = "0.13.0"
+version = "0.13.0-devel"
 dependencies = [
  "libc",
  "subprocess",
diff --git a/Cargo.toml b/Cargo.toml
index f4e7863..2a00a82 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,8 @@
 [package]
 name = "sonar"
-version = "0.13.0"
+version = "0.13.0-devel"
 edition = "2021"
+repository = "https://github.com/NordicHPC/sonar"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/README.md b/README.md
index 035de69..00ba842 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,10 @@ Options:
 
 ## Versions and release procedures
 
+### Version numbers
+
+The following basic versioning rules are new with v0.8.0.
+
 We use semantic versioning.  The major version is expected to remain at zero for the foreseeable
 future, reflecting the experimental nature of Sonar.
 
@@ -47,23 +51,35 @@ itself changes.  For example, v0.8.0 both added fields and stopped printing fiel
 The bugfix version is updated for changes that do not alter the output format per se but that might
 affect the output nevertheless, ie, most changes not covered by changes to the minor version number.
 
-The versioning rules are new with v0.8.0.
+### Release branches, uplifts and backports
+
+The following branching scheme is new with v0.12.x.
+
+The `main` branch is used for development and has a version number of the form `M.N.O-PRE` where
+"PRE" is some arbitrary string, eg "devel", "rc4".  Note that this version number form will also be
+present in the output of `sonar ps`, to properly tag those data.  If clients are exposed to
+prerelease `ps` data they must be prepared to deal with this.
 
 For every freeze of the the minor release number, a new release branch is created in the repo with
 the name `release_<major>_<minor>`, again we expect `<major>` to remain `0` for the foreseeable
-future, ergo, `release_0_12` is the v0.12.x release branch.  At that time, the minor release number
-is to be incremented on main.
+future, ergo, `release_0_12` is the v0.12.x release branch.  At branching time, the minor release
+number is incremented on main (so when we created `release_0_12` for v0.12.1, the version number on
+`main` went to `0.13.0-devel`).  The version number on a release branch is strictly of the form
+M.N.O.
 
-The branching scheme is new with v0.12.x.
+When a release `M.N.O` is to be made from a release branch, a tag is created of the form
+`release_M_N_O` on that branch and the release is built from that changeset.  Once the release has
+shipped, the bugfix version number on the branch is incremented.
 
-With the branches come some additional rules:
+With the branches come some additional rules for how to move patches around:
 
-- If a bugfix is made to a release branch it shall be uplifted to main at the time it is made.
+- If a bugfix is made to a release branch it shall be uplifted to main at the time it has been
+  verified, if the bug is present on main.
 - If a bugfix is made to main it shall be considered whether it should be backported the most
   recent release branch.  No older release branches shall automatically be considered for
   backports.
 
-### Changes in v0.13.x (on `main`)
+### Changes in v0.13.x-devel (on `main`)
 
 Version in progress, no changes as of yet.
 
diff --git a/src/main.rs b/src/main.rs
index 3ae3601..91dbb01 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -58,6 +58,7 @@ enum Commands {
     },
     /// Extract system information
     Sysinfo {},
+    Version {},
 }
 
 fn main() {
@@ -113,6 +114,9 @@ fn main() {
         Commands::Sysinfo {} => {
             sysinfo::show_system(&timestamp);
         }
+        Commands::Version {} => {
+            show_version(&mut std::io::stdout());
+        }
     }
 }
 
@@ -205,6 +209,7 @@ fn command_line() -> Commands {
                 }
             }
             "sysinfo" => Commands::Sysinfo {},
+            "version" => Commands::Version {},
             "help" => {
                 usage(false);
             }
@@ -265,8 +270,13 @@ fn usage(is_error: bool) -> ! {
     let mut stdout = std::io::stdout();
     let mut stderr = std::io::stderr();
     let out: &mut dyn std::io::Write = if is_error { &mut stderr } else { &mut stdout };
+
+    show_version(out);
+    let _ = out.write(env!("CARGO_PKG_REPOSITORY").as_bytes());
     let _ = out.write(
-        b"Usage: sonar <COMMAND>
+        b"
+
+Usage: sonar <COMMAND>
 
 Commands:
   ps       Take a snapshot of the currently running processes
@@ -302,3 +312,9 @@ Options for `ps`:
     let _ = out.flush();
     std::process::exit(if is_error { USAGE_ERROR } else { 0 });
 }
+
+fn show_version(out: &mut dyn std::io::Write) {
+    let _ = out.write(b"sonar version ");
+    let _ = out.write(env!("CARGO_PKG_VERSION").as_bytes());
+    let _ = out.write(b"\n");
+}


Test patch:
diff --git a/tests/ps-syntax.sh b/tests/ps-syntax.sh
index 758f754..579cbf9 100755
--- a/tests/ps-syntax.sh
+++ b/tests/ps-syntax.sh
@@ -21,7 +21,7 @@ if [[ $count -le 0 ]]; then
     exit 1
 fi
 l=$(head -n 1 <<< $output)
-if [[ !( $l =~ ^v=[0-9]+\.[0-9]+\.[0-9], ) ]]; then
+if [[ !( $l =~ ^v=[0-9]+\.[0-9]+\.[0-9](-.+)?, ) ]]; then
     echo "Version missing, got $l"
     exit 1
 fi