<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>2718.us blog &#187; version numbering</title>
	<atom:link href="http://2718.us/blog/tag/version-numbering/feed/" rel="self" type="application/rss+xml" />
	<link>http://2718.us/blog</link>
	<description>Miscellaneous Technological Geekery</description>
	<lastBuildDate>Tue, 18 May 2010 02:42:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Integrating Version Control Revisions in Mac App Version Numbers</title>
		<link>http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/</link>
		<comments>http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 13:57:26 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[build script]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[version control]]></category>
		<category><![CDATA[version number]]></category>
		<category><![CDATA[version numbering]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=238</guid>
		<description><![CDATA[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 REV=`svnversion -n &#34;${PROJECT_DIR}&#34;` REV=$&#123;REV/#[0-9]*:/} REV=$&#123;REV//&#91;^0-9&#93;/&#125; BASE=`/usr/libexec/PlistBuddy [...]]]></description>
			<content:encoded><![CDATA[<p>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:</p>
<div class="geshi no bash">
<div class="head"># tack the subversion revision number onto the CFBundleVersion</div>
<ol>
<li class="li1">
<div class="de1"><span class="re2">REV=</span>`svnversion -n <span class="st0">&quot;${PROJECT_DIR}&quot;</span>`</div>
</li>
<li class="li1">
<div class="de1"><span class="re2">REV=</span>$<span class="br0">&#123;</span>REV<span class="sy0">/</span><span class="co0">#[0-9]*:/}</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">REV=</span>$<span class="br0">&#123;</span>REV<span class="sy0">//</span><span class="br0">&#91;</span>^<span class="nu0">0</span><span class="nu0">-9</span><span class="br0">&#93;</span><span class="sy0">/</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">BASE=</span>`<span class="sy0">/</span>usr<span class="sy0">/</span>libexec<span class="sy0">/</span>PlistBuddy -c <span class="st0">&quot;Print :CFBundleVersion&quot;</span> <span class="st0">&quot;${PROJECT_DIR}/Info.plist&quot;</span>`</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">/</span>usr<span class="sy0">/</span>libexec<span class="sy0">/</span>PlistBuddy -c <span class="st0">&quot;Set :CFBundleVersion $BASE.$REV&quot;</span> <span class="st0">&quot;${TARGET_BUILD_DIR}/${INFOPLIST_PATH}&quot;</span></div>
</li>
</ol>
</div>
<p>This takes the CFBundleVersion from the project&#8217;s Info.plist, adds a period and the subversion revision number, and injects that into the Info.plist of the built product.</p>
<p>When I made the move to Mercurial, I couldn&#8217;t quite do this anymore.  While subversion revision numbers are <a href="http://mathworld.wolfram.com/MonotoneIncreasing.html">monotone increasing</a> and consistent everywhere (they are the unique identifiers of a particular version), Mercurial&#8217;s &#8220;revision numbers&#8221; 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.</p>
<p>Though it took some time, I&#8217;ve finally come to a system with Mercurial that I think is workable:</p>
<div class="geshi no bash">
<div class="head"># use the number of minutes between the tip and the most recent tagged commit</div>
<ol>
<li class="li1">
<div class="de1"><span class="re2">HG_LAST_TAG_TIMESTAMP=</span>$<span class="br0">&#40;</span><span class="sy0">/</span>usr<span class="sy0">/</span><span class="kw3">local</span><span class="sy0">/</span>bin<span class="sy0">/</span>hg log -r <span class="st0">&quot;$(/usr/local/bin/hg log -r &#39;.&#39; &#8211;template &#39;{latesttag}&#39; &#8211;repository &quot;</span><span class="re0">$<span class="br0">&#123;</span>PROJECT_DIR<span class="br0">&#125;</span><span class="sy0">|</span>><span class="st0">&quot;)&quot;</span> &#8211;template <span class="st0">&quot;{date|hgdate}<span class="es0">\n</span>&quot;</span> &#8211;repository <span class="st0">&quot;${PROJECT_DIR}&quot;</span> <span class="sy0">|</span> <span class="kw2">cut</span> -f1 -d<span class="st0">&#39; &#39;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">HG_TIP_TIMESTAMP=</span>$<span class="br0">&#40;</span><span class="sy0">/</span>usr<span class="sy0">/</span><span class="kw3">local</span><span class="sy0">/</span>bin<span class="sy0">/</span>hg log -r <span class="st0">&#39;.&#39;</span> &#8211;template <span class="st0">&quot;{date|hgdate}<span class="es0">\n</span>&quot;</span> &#8211;repository <span class="st0">&quot;${PROJECT_DIR}&quot;</span> <span class="sy0">|</span> <span class="kw2">cut</span> -f1 -d<span class="st0">&#39; &#39;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">REV=</span>$<span class="br0">&#40;</span><span class="br0">&#40;</span> <span class="br0">&#40;</span><span class="re1">$HG_TIP_TIMESTAMP</span> &#8211; <span class="re1">$HG_LAST_TAG_TIMESTAMP</span><span class="br0">&#41;</span> <span class="sy0">/</span> <span class="nu0">60</span> <span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">BASE=</span>`<span class="sy0">/</span>usr<span class="sy0">/</span>libexec<span class="sy0">/</span>PlistBuddy -c <span class="st0">&quot;Print :CFBundleVersion&quot;</span> <span class="st0">&quot;${PROJECT_DIR}/Info.plist&quot;</span>`</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">/</span>usr<span class="sy0">/</span>libexec<span class="sy0">/</span>PlistBuddy -c <span class="st0">&quot;Set :CFBundleVersion $BASE.$REV&quot;</span> <span class="st0">&quot;${TARGET_BUILD_DIR}/${INFOPLIST_PATH}&quot;</span></div>
</li>
</ol>
</div>
<p>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&#8217;s time-based, it is guaranteed to be monotone increasing, consistent, and unique (well, provided multiple commits don&#8217;t happen within a 1-minute span, which is safe for me).</p>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

