This plugin gathers version information and embeds it into the package/executable, in a way that allows it to be retrieved at runtime.
We actually generate a few files:
- a
Version.swift
file which then gets built into the package - an
Info.plist
file which gets embedded as a package resource - a
Info.plisth
a C-style header file, with a non-standard extension so that is bundled into the resources
See https://github.com/elegantchaos/VersionatorTest for an example command line tool which uses the plugin.
The generated Swift API defines a CurrentVersion
struct, with some static properties:
public struct VersionatorVersion {
static let string = "1.0.0"
static let build = 4
static let commit = "g70f8f9a"
static let git = "v1.0.0-0-g70f8f9a"
static let tag = "v1.0.0"
static let full = "1.0.0 (4)"
}
The build number is derived from the git commit count on the current branch. This is a fairly standard technique.
The git-style string is derived from the latest version tag on the current branch.
Currently I'm just returning it verbatim, but the plugin could be extended to parse this more fully.
This plugin also generates an Info.plist
, which gets bundled into the package resources.
This can then be accessed with Bundle.module.infoDictionary
.
For Xcode-based applications, the Info.plist
will probably need to include many other values, so using the file generated by Versionator won't be an option.
In this case, a better approach is to have a local package which uses the Versionator plugin, and to then set the INFOPLIST_PREFIX_HEADER
to point at the generated Info.plisth
file in the local package's resource bundle.
This file defines some variables:
#define BUILD 4
#define CURRENT_PROJECT_VERSION 4
#define COMMIT "70f8f9a"
#define GIT_VERSION "v1.0.0-0-g70f8f9a"
#define GIT_TAG "v1.0.0"
You can then substitute these into your Info.plist
definitions, using the normal synax - e.g: ${GIT_VERSION}
.
Note that we use a non-standard file extension here to avoid Swift Package Manager getting confused. Generating a .h
file will cause SPM to treat the package as being mixed Swift/C, which is not allowed in this context.
For an alternative approach to generating an Info.plist, see also Infomatic Plugin.
Note: Outputting Info.plist resource from a build tool like this seems to produce an error in Xcode:
note: Run script build phase 'Calculating Version' will be run during every build because the option to run the script phase "Based on dependency analysis" is unchecked. (in target 'VersionatorTest_VersionatorTestWithResources' from project 'VersionatorTest')
warning: duplicate output file '/Users/sam/Library/Developer/Xcode/DerivedData/VersionatorTest-ejghobxgggddhabfxovpkctjsdcf/Build/Products/Debug-iphoneos/VersionatorTest_VersionatorTestWithResources.bundle/Info.plist' on task: ProcessInfoPlistFile /Users/sam/Library/Developer/Xcode/DerivedData/VersionatorTest-ejghobxgggddhabfxovpkctjsdcf/Build/Products/Debug-iphoneos/VersionatorTest_VersionatorTestWithResources.bundle/Info.plist /Users/sam/Library/Developer/Xcode/DerivedData/VersionatorTest-ejghobxgggddhabfxovpkctjsdcf/Build/Intermediates.noindex/VersionatorTest.build/Debug-iphoneos/VersionatorTest_VersionatorTestWithResources.build/empty-VersionatorTest_VersionatorTestWithResources.plist (in target 'VersionatorTest_VersionatorTestWithResources' from project 'VersionatorTest')
I'm not sure if this is a bug with the Xcode integration, or if there's a recommended workaround. The best approach may be to add a local package to your Xcode project and have that use the plugin.