Version Info in Swift CLI tools

I have a simple task… I just want to output a version number when I run langsrv -v. Is that so hard? Well, if you’re using Swift, yes.

I make mistakes, so manual steps for me are both error prone and tiresome. When I update the version, I also need to make sure my git tag will be correct. So… how do we accomplish this in Swift?

Just follow these easy steps!

  1. Create a Makefile – yep, just get used to it. SwiftPM should be though of as simply the mechanism to save you from writing some of the swiftc arguments directly. Sure, it also makes downloading some dependencies a bit easier too.
  2. Create a new module, say VersionInfo.
  3. Create a template Swift file, say VersionInfo.swifttemplate
  4. Create a version info file, say VersionInfo.yaml
  5. Create a script that will parse that VersionInfo.yaml file and generate the appropriate VersionInfo.swift file.
  6. Import your VersionInfo module in your main.swift file.
  7. Reference that version info however you’d like.
  8. Update your Makefile to include a tag  to create the correct git tag.

Yeah… I think that is all of the steps.

Here’s my Makefile:


.PHONY: release debug clean generate-version tag
debug: generate-version
swift build -c debug
swift test -c debug
release: generate-version
swift build -c release -Xswiftc -static-stdlib
swift test -c release
clean:
swift package clean
generate-version:
./Scripts/genvers.sh
tag:
git tag "v$(shell sed 's/^version: \(.*\)/\1/' ./Sources/VersionInfo/VersionInfo.yaml)"

view raw

Makefile

hosted with ❤ by GitHub

Any my genvers.sh script:


#!/bin/bash
VersionInfoTemplatePath=./Sources/VersionInfo/VersionInfo.swiftpartial
VersionInfoPath=./Sources/VersionInfo/VersionInfo.swift
VersionInfo=./Sources/VersionInfo/VersionInfo.yaml
Version=$(sed 's/^version: \(.*\)$/\1/' $VersionInfo)
sed "s/\$VersionNumber/$Version/g" <$VersionInfoTemplatePath >$VersionInfoPath

view raw

genvers.sh

hosted with ❤ by GitHub

And my VersionInfo.swifttemplate file:


.PHONY: release debug clean generate-version tag
debug: generate-version
swift build -c debug
swift test -c debug
release: generate-version
swift build -c release -Xswiftc -static-stdlib
swift test -c release
clean:
swift package clean
generate-version:
./Scripts/genvers.sh
tag:
git tag "v$(shell sed 's/^version: \(.*\)/\1/' ./Sources/VersionInfo/VersionInfo.yaml)"

view raw

Makefile

hosted with ❤ by GitHub

And finally, my VersionInfo.yaml file:

version: 0.9.2

Now when I want to update the version, I simply edit the VersionInfo.yaml file, build, and run make tag before I push my changes.

Of course, if we had compiler variables in Swift, I could have avoided nearly all of this work…

Version Info in Swift CLI tools