2718.us blog » version number http://2718.us/blog Miscellaneous Technological Geekery Tue, 18 May 2010 02:42:55 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 Integrating Version Control Revisions in Mac App Version Numbers http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/ http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/#comments Mon, 22 Mar 2010 13:57:26 +0000 2718.us http://2718.us/blog/?p=238 When I was using Subversion for version control in working on my Mac apps in Xcode, I had come to use a build script phase to tack on the subversion revision number as the last part to the version number:

# tack the subversion revision number onto the CFBundleVersion
  1. REV=`svnversion -n "${PROJECT_DIR}"`
  2. REV=${REV/#[0-9]*:/}
  3. REV=${REV//[^0-9]/}
  4. BASE=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${PROJECT_DIR}/Info.plist"`
  5. /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASE.$REV" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

This takes the CFBundleVersion from the project’s Info.plist, adds a period and the subversion revision number, and injects that into the Info.plist of the built product.

When I made the move to Mercurial, I couldn’t quite do this anymore.  While subversion revision numbers are monotone increasing and consistent everywhere (they are the unique identifiers of a particular version), Mercurial’s “revision numbers” are local to a particular instance of the repository and may not match up from one instance to another.  Mercurial uses a hash as the unique identifier of a particular version, and these hexadecimal hashes are not monotone, making them unsuitable for use in CFBundleVersion.

Though it took some time, I’ve finally come to a system with Mercurial that I think is workable:

# use the number of minutes between the tip and the most recent tagged commit
  1. HG_LAST_TAG_TIMESTAMP=$(/usr/local/bin/hg log -r "$(/usr/local/bin/hg log -r '.' –template '{latesttag}' –repository "${PROJECT_DIR}|>")" –template "{date|hgdate}\n" –repository "${PROJECT_DIR}" | cut -f1 -d' ')
  2. HG_TIP_TIMESTAMP=$(/usr/local/bin/hg log -r '.' –template "{date|hgdate}\n" –repository "${PROJECT_DIR}" | cut -f1 -d' ')
  3. REV=$(( ($HG_TIP_TIMESTAMP$HG_LAST_TAG_TIMESTAMP) / 60 ))
  4. BASE=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${PROJECT_DIR}/Info.plist"`
  5. /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASE.$REV" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

This calculates the number of minutes between the most recent tagged ancestor of the tip and the tip itself and adds that to the CFBundleVersion.  Because it’s time-based, it is guaranteed to be monotone increasing, consistent, and unique (well, provided multiple commits don’t happen within a 1-minute span, which is safe for me).

]]>
http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/feed/ 0