Should I store and provide version command for executable and how to do it?


I would like to know if I should store and provide a --version flag for resulting executable and how to do it.


I have a library that is developed in SPM. It provides executable for our project. This executable has a version of its own and also a version of its dependencies.
Here I should notice that one version of one dependency is very important and could be a part of version of this executable.

I want to add --version flag for this executable. However, to add this flag, I need to know how to store a version.

I could either store it in a code or in a resource (VERSION file, for example) or read it from Package.swift or even read it from its dependencies.

One of its dependencies (import dependency which version I want to see) does contain neither version flag nor version structure in a library. Actually, it is a library.

How could I solve these two problems:

  1. Figure out which version of import dependency I have.
  2. Figure out which version of result executable I have.

Share your practices, please.

( Especially you, SwiftSyntax ).

What I typically do is write out a Version.swift file with a version string constant on release builds (overwriting a stub) with the version from git.

So for instance, I have a Version.swift placeholder:

let AppVersion = "undefined version: run 'make version' to update"

and a Makefile section:

VERSION := $(shell git describe --always --tags --dirty)
VERSION_FILE = Sources/ArenaCore/Version.swift


release: version build-release

install: release
	install .build/release/arena /usr/local/bin/
	@# reset version file
	@git checkout $(VERSION_FILE)

	@# avoid tracking changes for file:
	@git update-index --assume-unchanged $(VERSION_FILE)
	@echo "public let AppVersion = \"$(VERSION)\"" > $(VERSION_FILE)

The --version flag simply logs AppVersion and exits.

This is from GitHub - finestructure/Arena: A command line tool to create Swift Playground projects with SPM package dependencies in case you want to look at the details.

It's a bit convoluted but I haven't found an easier way to set this up.

A question about version file. It only exists in a repository with default state, but it doesn't keep changes of current version, right?
It always contains "undefined version: run 'make version' to update", but it's copies in releases will contain current version.

Yes, exactly.

My thinking is that when looking at the repository I can tell from the state and history what version I'm at so I don't need the file's contents. When I've got the build artifact however, it's detached from the repo history and so this is a way to "smuggle" in the revision info via the placeholder file.

I use this logic for my GitHub Action/NPM package: install-swift-tool/Makefile at master ยท Cyberbeni/install-swift-tool (
So in debug, the version is always "0.0.0" and it only gets changed for publishing.
(I don't want to publish a new version for the package when only the dependencies are updated for my Action but their new version doesn't contain any crucial updates, so I do this manually instead of in a workflow triggered by a release.)