<?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>esmithy.net</title>
	<atom:link href="http://esmithy.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://esmithy.net</link>
	<description>Stuff Hammered Out by Eric Smith</description>
	<lastBuildDate>Wed, 25 Jan 2012 01:21:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Kindle for Technical Reading</title>
		<link>http://esmithy.net/2012/01/24/kindle-for-technical-reading/</link>
		<comments>http://esmithy.net/2012/01/24/kindle-for-technical-reading/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 01:21:48 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=526</guid>
		<description><![CDATA[I&#8217;ve read several novels in Amazon Kindle format (on an actual Kindle device, the PC client, or an iPad), and the experience is pretty good. But having now finished reading a technical book that way, I think there is plenty of room for improvement. The book I read is Jez Humble and David Farley&#8217;s Continuous Delivery: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve read several novels in Amazon Kindle format (on an actual Kindle device, the PC client, or an iPad), and the experience is pretty good. But having now finished reading a technical book that way, I think there is plenty of room for improvement.</p>
<p><span id="more-526"></span>The book I read is Jez Humble and David Farley&#8217;s<em> <a href="http://www.amazon.com/gp/product/B003YMNVC0/ref=as_li_ss_tl?ie=UTF8&amp;tag=sparksfromthesmi&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B003YMNVC0">Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation</a>. </em>I&#8217;m not sure if the weaknesses are due to Amazon&#8217;s ebook platform, this particular title, or some combination of both, but these were the issues I had:</p>
<ol>
<li>The table of contents as displayed by the PC reader application, isn&#8217;t detailed enough.  The book is divided into three sections, and the sections appear in the ToC, but none of the chapters in the sections do. One of the entries in the ToC is the Contents as it appears in the book itself (which is also where you go if you choose Table of Contents from the iPad menu). It has links to everywhere, but is extremely detailed and spans 19 pages, making it cumbersome to use. There&#8217;s no easy way to just jump to a particular chapter.</li>
<li>Cross references don&#8217;t tell where they&#8217;re going in a meaningful way. They reference other parts of the book by page number, but Kindle books don&#8217;t have page numbers. There <em>is</em> a link, so not all is lost, but I couldn&#8217;t tell if a cross reference was to some part of the book I had already read (and that I ought to therefore nod and say, &#8220;Oh, yeah&#8221;) or somewhere later on. Maybe just a little arrow icon pointing left or right would have been a good hint.</li>
<li>The index is cumbersome. There aren&#8217;t any links to jump to the different letter sections, so if you want to look up &#8220;Tests&#8221;, be prepared to flip through <em>a lot</em> of pages to get to the T&#8217;s.</li>
<li>The figures are too low-res. One in particular, 15.1, was almost completely unreadable. It sounded like a really interesting chart, but it was just too small and couldn&#8217;t be zoomed so I feel kind of cheated out of that.</li>
<li> Compound words were problematic because the dashes were usually dropped and the words mashed together. Apparently someone/something confused them  with dashes as a result of layout (to split words across lines) and dropped them all.</li>
</ol>
<p>It seems possible that Apple, with their new iBooks 2 platform and its textbook focus,  could end up being a better experience for technical books like this. I&#8217;ll be interested to give it a try.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2012/01/24/kindle-for-technical-reading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updating an Amazon Linux AMI to Python 2.7</title>
		<link>http://esmithy.net/2012/01/12/updating-an-amazon-linux-ami-to-python-2-7/</link>
		<comments>http://esmithy.net/2012/01/12/updating-an-amazon-linux-ami-to-python-2-7/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 17:22:43 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=509</guid>
		<description><![CDATA[I&#8217;ve been doing some work with Linux lately, a new thing for me, and feel a bit like I&#8217;ve been thrown into the deep end and told to swim. Today I updated Python to version 2.7 on an EC2 instance. Amazon Linux (Basic 64-bit Amazon Linux AMI 2011.09 AMI Id: ami-1b814f72) currently comes with Python [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing some work with Linux lately, a new thing for me, and feel a bit like I&#8217;ve been thrown into the deep end and told to swim. Today I updated Python to version 2.7 on an EC2 instance.</p>
<p><span id="more-509"></span></p>
<p>Amazon Linux (Basic 64-bit Amazon Linux AMI 2011.09 AMI Id: ami-1b814f72) currently comes with Python 2.6.7 on it. At first, I thought I&#8217;d just be able to update to 2.7 with yum, but as far as I can tell, there isn&#8217;t a package for that already. </p>
<p>Joshua Holmes <a href="http://joshualholmes.wordpress.com/category/amazon-ec2/">wrote</a> about updating Python, which was a great help. My experienced varied a little, so I thought I&#8217;d share in case it is useful to someone else. For example, I didn&#8217;t want sqllite, but I did want ssl support. Also, there were some cases where I needed to use <code>sudo</code> when logged in as ec2-user.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">gcc</span> gcc-c++
<span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> openssl-devel.x86_64
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> ~
<span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>python.org<span style="color: #000000; font-weight: bold;">/</span>ftp<span style="color: #000000; font-weight: bold;">/</span>python<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2.7</span><span style="color: #000000; font-weight: bold;">/</span>Python-<span style="color: #000000;">2.7</span>.tgz
<span style="color: #c20cb9; font-weight: bold;">tar</span> xfz Python-<span style="color: #000000;">2.7</span>.tgz
<span style="color: #7a0874; font-weight: bold;">cd</span> Python-<span style="color: #000000;">2.7</span>
.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>python2.7 <span style="color: #660033;">--with-threads</span> <span style="color: #660033;">--with-ssl</span> <span style="color: #660033;">--enable-shared</span>
<span style="color: #c20cb9; font-weight: bold;">make</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> ~ 
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">''</span><span style="color: #ff0000;">'
 alias python='</span><span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>python2.7<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python<span style="color: #ff0000;">'
 PATH=$PATH:/opt/python2.7/bin
 '</span><span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> .bash_profile
<span style="color: #7a0874; font-weight: bold;">source</span> .bash_profile
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">''</span><span style="color: #ff0000;">'
 /opt/python2.7/lib
 '</span><span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> opt-python2.7.conf
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> opt-python2.7.conf  <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ld.so.conf.d<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> ldconfig
&nbsp;
python <span style="color: #660033;">-V</span>
Python <span style="color: #000000;">2.7</span></pre></td></tr></table></div>

<h4>Notes</h4>
<p>Line 26 is output from Python &#8212; not something you input (if that wasn&#8217;t obvious).</p>
<p>The <code>configure</code> script (line 8 ) specifies which optional libraries will be included in Python. I&#8217;m not sure what the typical list includes (for example, which are included in the official Python install for Windows?), but when you run <code>make</code> (line 9), it will report all the missing libraries for Python modules (&#8220;Python build finished, but the necessary bits to build these modules were not found&#8221;). If you use a module with a missing library in a Python program, you&#8217;ll get a runtime error.</p>
<p>The <code>echo</code> lines (13-16) are editing your user profile file for bash so that when you type &#8216;python&#8217; you&#8217;ll get the 2.7 version instead of the default 2.6.7 version. I had a situation where I needed to run python under <code>sudo</code>, but root doesn&#8217;t have the alias, so it kept running 2.6.7. After some unfruitful attempts to add the alias to /etc/profile (<code>sudo</code> doesn&#8217;t execute that), I just added a symlink and invoked &#8216;python2.7&#8242; explicitly (thanks to Chris Brinker):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>python2.7<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>python2.7
<span style="color: #c20cb9; font-weight: bold;">sudo</span> python2.7 <span style="color: #660033;">-V</span>
Python <span style="color: #000000;">2.7</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2012/01/12/updating-an-amazon-linux-ami-to-python-2-7/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Holiday Amazon Box Problem</title>
		<link>http://esmithy.net/2011/12/26/the-holiday-amazon-box-problem/</link>
		<comments>http://esmithy.net/2011/12/26/the-holiday-amazon-box-problem/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 22:45:56 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=502</guid>
		<description><![CDATA[By the time Christmas comes around, our house is usually awash with boxes from Amazon. It gets a bit tricky at that point, because I&#8217;m never sure if the box is something I ordered to give to my family, or something someone else sent me as a gift. In the former case, I&#8217;ll want to [...]]]></description>
			<content:encoded><![CDATA[<p>By the time Christmas comes around, our house is usually awash with boxes from Amazon. It gets a bit tricky at that point, because I&#8217;m never sure if the box is something I ordered to give to my family, or something someone else sent me as a gift. In the former case, I&#8217;ll want to wrap it and put it under the tree. In the latter, a lot of times my wife will wrap it on behalf of the giver so it can still be a surprise Christmas morning. The problem is telling them apart.</p>
<p><span id="more-502"></span></p>
<p>I guess I&#8217;m not the only one with this problem. A friend sent me a message thanking me for a gift basket I&#8217;d sent him a couple of weeks ago. He hadn&#8217;t opened it until it was time to start wrapping all the presents he&#8217;d ordered himself from Amazon. Hopefully the food was still edible.</p>
<p>At first I was thinking that Amazon needs to figure out how to solve that problem. If I were Amazon, I might just suggest gift wrapping presents to others so that it is always safe to open the box, but gift wrap starts to get expensive &#8212; especially if you have several less-expensive items.</p>
<p>Another solution is to address the packages in a way that differentiates them. I&#8217;ve changed my wishlist address so that it includes &#8220;(Wishlist)&#8221; after my name. My regular ordering address now has &#8220;(Self Order)&#8221; after my name. Now maybe I just need to add &#8220;(A gift for you)&#8221; after the names of my friends to tip them off.</p>
<p>I guess I&#8217;ll see how it goes&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/12/26/the-holiday-amazon-box-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I want my webOS</title>
		<link>http://esmithy.net/2011/10/15/i-want-my-webos/</link>
		<comments>http://esmithy.net/2011/10/15/i-want-my-webos/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 22:02:56 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=482</guid>
		<description><![CDATA[It&#8217;s become fairly clear that HP is not webOS&#8217; savior. It&#8217;s also unlikely that webOS can come back from the dead for the second time. But it makes me sad, since webOS and its devices hit a sweet spot that no one managed to exploit. The currently winning smartphone platforms are the gated and guarded [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s become fairly clear that HP is not webOS&#8217; savior. It&#8217;s also unlikely that webOS can come back from the dead for the second time. But it makes me sad, since webOS and its devices hit a sweet spot that no one managed to exploit.</p>
<p><span id="more-482"></span></p>
<p>The currently winning smartphone platforms are the gated and guarded community of iOS, and the wild-west of Android. Palm/HP had the vertical integration of Apple with the openness of Google. Maybe in today&#8217;s polarized society, the middle has no appeal. But don&#8217;t think that when I say &#8220;middle&#8221; I mean not as good as either extreme &#8212; it&#8217;s more like the best of both worlds.</p>
<p>Here are some of my favorite features of webOS:</p>
<ol>
<li>Fantastic muti-tasking that no one else has yet matched.</li>
<li>A UI that is is richer than iOS and more beautiful than Android.</li>
<li>Over-the-air activation/updates/etc. Attaching it to a PC is never required.</li>
<li>Unobtrusive notifications that can be ignored without being lost.</li>
<li>Merging all of your contacts/calendars from wherever they happen to live.</li>
<li>Acceptance that Flash is still a significant web technology.</li>
<li>No jailbreaking required &#8211; but rather a completely sanctioned developer mode that gives you root access to the device.</li>
<li>HTML 5 application development as a first class citizen.</li>
<li>C++ application development for gaming, etc.</li>
<li>A cloud-based IDE allowing app development in a browser.</li>
<li>It is Linux, so skills are transferable.</li>
<li>Inductive charging, so you don&#8217;t have to plug in cords &#8212; just drop it on the charger (OK, technically a hardware feature rather than webOS per se, but still awesome).</li>
</ol>
<p>I have applications that I wrote myself or with co-workers in both the HP App Catalog and the Apple App Store. I definitely prefer coding in JavaScript as opposed to Objective-C, but the thing that makes my blood boil in comparing the experience is Apple&#8217;s provisioning profile system. It&#8217;s as if Apple said, &#8220;Please poke yourself in the eye at regular intervals so that we can be sure you&#8217;ve paid us your developer program fees.&#8221; Having developed and submitted for webOS, it becomes obvious how pointless the Apple system is. I wouldn&#8217;t go to the trouble for a personal project &#8212; but what does Apple care about that?</p>
<p>I haven&#8217;t developed for Android, but I like Java, so it could be a good experience. But the Android ecosystem <a href="http://news.cnet.com/8301-31322_3-20120623-256/dear-android-this-is-your-last-chance/?tag=rtcol">seems like total chaos</a>.</p>
<p>I did do some preliminary investigation into developing a video-centric application for Android, but got stuck when trying to figure out what video decoder support exists for the platform. Sure, there&#8217;s something that says H.264 is supported, but at what level and profile? Those are kind of critical to know, but the information just isn&#8217;t available. I guess Google just left it up to the device manufacturers to do what they wanted, which means trying to figure it out for every device. Compare that to the <a href="https://developer.palm.com/content/api/reference/services/video.html#supported-video-formats">webOS information on video formats</a>.</p>
<p>So I find myself in an unfortunate situation, hanging on to an aging phone and not sure what I&#8217;d do if I accidentally dropped it on the sidewalk tomorrow. Maybe, like I did the last time Palm imploded (with Palm OS), I&#8217;d have to give Windows a try, and hope that it isn&#8217;t the soul-less experience it was last time.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/10/15/i-want-my-webos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Batch File Libraries</title>
		<link>http://esmithy.net/2011/07/12/batch-file-libraries/</link>
		<comments>http://esmithy.net/2011/07/12/batch-file-libraries/#comments</comments>
		<pubDate>Wed, 13 Jul 2011 02:19:29 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=466</guid>
		<description><![CDATA[I&#8217;ve always considered batch files as kind of ghetto. Anything too complex devolves into a morass of gotos and labels. But I recently put together some install batch scripts that I was actually pleased with, including a clean mechanism for sharing common code. A while back, I used WiX to build an installer, which was [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always considered batch files as kind of ghetto. Anything too complex devolves into a morass of gotos and labels. But I recently put together some install batch scripts that I was actually pleased with, including a clean mechanism for sharing common code.</p>
<p><span id="more-466"></span>A while back, I used <a href="http://wix.sourceforge.net/">WiX</a> to build an installer, which was handed off to IT to deploy a web site. After a fair amount of anguish and frustration, I eventually realized that my installer was essentially a difficult to create and maintain batch file. Half the project was just custom command calls out to appcmd.exe anyway. If you&#8217;re so unfortunate as to absolutely have to create an MSI install, WiX isn&#8217;t a bad way to go, but it was a layer of massive unnecessary complexity in my case. Instead, I ended up creating a <a href="http://www.msfn.org/board/topic/39048-how-to-make-a-7-zip-switchless-installer/">7zip self-extractor</a> that ran an actual batch file when launched.</p>
<p>One challenge is that I actually had a few installers, and I wanted to share code between them, which I was able to do after discovering the <a href="http://technet.microsoft.com/en-us/library/cc772743(WS.10).aspx">CALL</a> command. Here&#8217;s an example:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #00b100; font-weight: bold;">call</span> lib.cmd CopyFiles &quot;C:\ServiceInstallDir&quot;</pre></div></div>

<p>This is essentially a function call, where &#8220;CopyFiles&#8221; is the name of the function, and &#8220;lib.cmd&#8221; is the file where it is implemented. Arguments follow the name of the function, the destination directory being the single argument in this case.</p>
<p>The lib.cmd file looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #33cc33;">@</span><span style="color: #b1b100; font-weight: bold;">echo</span> off
<span style="color: #808080; font-style: italic;">REM Within the &quot;function&quot; the args will be shifted, so 3 here becomes 2, 2 becomes 1, etc.</span>
<span style="color: #00b100; font-weight: bold;">call</span> :<span style="color: #b100b1; font-weight: bold;">%<span style="color: #448888;">1</span></span> <span style="color: #33cc33;">%</span><span style="color: #448888;">2</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">3</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">4</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">5</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">6</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">7</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">8</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">9</span>
<span style="color: #00b100; font-weight: bold;">goto</span> :<span style="color: #b100b1; font-weight: bold;">EOF</span>
&nbsp;
:<span style="color: #b100b1; font-weight: bold;">Heading</span>
<span style="color: #808080; font-style: italic;">REM %1 - Text for heading</span>
<span style="color: #b1b100; font-weight: bold;">echo</span> ------------------------------------------------------
<span style="color: #b1b100; font-weight: bold;">echo</span> <span style="color: #33cc33;">^|</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">~1</span>
<span style="color: #b1b100; font-weight: bold;">echo</span> ------------------------------------------------------
<span style="color: #00b100; font-weight: bold;">goto</span> :<span style="color: #b100b1; font-weight: bold;">EOF</span>
&nbsp;
:<span style="color: #b100b1; font-weight: bold;">CopyFiles</span>
<span style="color: #808080; font-style: italic;">REM %1 - Install directory</span>
<span style="color: #00b100; font-weight: bold;">call</span> :<span style="color: #b100b1; font-weight: bold;">Heading</span> &quot;Copying files...&quot;
<span style="color: #00b100; font-weight: bold;">if</span> <span style="color: #000000; font-weight: bold;">exist</span> &quot;<span style="color: #33cc33;">%</span><span style="color: #448888;">~1</span>&quot; <span style="color: #b1b100; font-weight: bold;">rd</span> /s /q &quot;<span style="color: #33cc33;">%</span><span style="color: #448888;">~1</span>&quot;
<span style="color: #b1b100; font-weight: bold;">md</span> &quot;<span style="color: #33cc33;">%</span><span style="color: #448888;">~1</span>&quot;
xcopy *.* &quot;<span style="color: #33cc33;">%</span><span style="color: #448888;">~1</span>&quot; /s 
<span style="color: #00b100; font-weight: bold;">goto</span> :<span style="color: #b100b1; font-weight: bold;">EOF</span></pre></div></div>

<p>Each label in this file acts as a function call. The CALL at the beginning passes control off to the label, including the additional arguments. The function ends by jumping to the special :EOF label (which exits the batch context). Note also that functions can call each other, as where the &#8220;CopyFiles&#8221; function calls the &#8220;Heading&#8221; function.</p>
<p>It&#8217;s a great way to encapsulate little bits of functionality in a common place.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/07/12/batch-file-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sprint Makes Me Laugh</title>
		<link>http://esmithy.net/2011/05/23/sprint-makes-me-laugh/</link>
		<comments>http://esmithy.net/2011/05/23/sprint-makes-me-laugh/#comments</comments>
		<pubDate>Tue, 24 May 2011 03:19:43 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=457</guid>
		<description><![CDATA[I got this flyer from Sprint. I wonder if they wrote that &#8220;protecting more than ever before&#8221; with a straight face or what. &#160;]]></description>
			<content:encoded><![CDATA[<p>I got this flyer from Sprint. I wonder if they wrote that &#8220;protecting more than ever before&#8221; with a straight face or what.</p>
<p><span id="more-457"></span></p>
<p><img class="aligncenter size-full wp-image-458" title="Protecting more than ever before" src="http://esmithy.net/content/IMG-640x414-500x323.jpg" alt="Protecting more than ever before" width="500" height="323" /></p>
<p>&nbsp;<br />
<img class="aligncenter size-full wp-image-459" title="New program? $1 more!" src="http://esmithy.net/content/IMG_0001-500x463.jpg" alt="New program? $1 more!" width="500" height="463" /></p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/05/23/sprint-makes-me-laugh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OK, Maybe TurboTax Is Worth It</title>
		<link>http://esmithy.net/2011/03/28/ok-maybe-turbotax-is-worth-it/</link>
		<comments>http://esmithy.net/2011/03/28/ok-maybe-turbotax-is-worth-it/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 03:18:48 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=445</guid>
		<description><![CDATA[I was a bit of a masochist this year. I actually did my federal taxes twice, trying to figure out if there is a cheaper alternative to using TurboTax. But TurboTax, in spite of costing more, ended up being the cheaper option by a long shot. The whole United States tax system is a mess. [...]]]></description>
			<content:encoded><![CDATA[<p>I was a bit of a masochist this year. I actually did my federal taxes twice, trying to figure out if there is a cheaper alternative to using TurboTax. But TurboTax, in spite of costing more, ended up being the cheaper option by a long shot.<br />
<span id="more-445"></span><br />
The whole United States tax system is a mess. That the average citizen can&#8217;t pay their taxes without some kind of help just irks me. That so many people rely on that fact for their livelihood (tax accountants, software makers, etc.) and that it is easier for congress to throw something into the tax code than introduce real legislation convinces me that it is unlikely to change anytime soon.</p>
<p>General rant aside, I also get tired of paying $60 for TurboTax every year, so I cancelled my automatic subscription, determined to try something else this time around. After reading some reviews, I decided to go with <a href="http://www.taxact.com/">TaxACT Online</a>, which looked to be reasonably good and quite a bit less expensive. The nice thing is that you can use the application for free until you&#8217;re ready to actually file or print your return.</p>
<p>There were a few times that I felt unsure about what I was doing while doing my return &#8212; I had some employee stock purchase program things last year to complicate matters. I eventually made it through, though, itemizing my deductions since I&#8217;ve got mortgage interest and lots of charitable donations. My remaining federal tax liability at the end was around $500. </p>
<p>That felt wrong to me. I don&#8217;t think I&#8217;ve <em>ever</em> owed federal taxes beyond what had already been withheld. State taxes, sure &#8212; I frequently owe some there &#8212; but owing federal taxes was enough to encourage me to take a run through <a href="http://turbotax.intuit.com/tax-tools/calculators/taxcaster/">TurboTax&#8217;s estimator</a>. That gave me hope that I might be able to get a more favorable result.</p>
<p>Doing taxes is far from fun, but it was definitely easier with <a href="https://turbotax.intuit.com/login/start.jsp?priorityCode=3468337910&#038;productid=16&#038;abtest=PONHelp%3DC%26feereview%3DC%26EFSelection%3DB%26MintBranded%3DB">TurboTax Online</a>. I felt more like I was being guided along rather than being presented with a bunch of text to read and some form inputs to fill in. I was also able to import a lot of data electronically, which helped with both speed and accuracy. When I finished my federal return (for the second time), I came out with about a $1500 <em>refund</em>.</p>
<p>Maybe I did something wrong with TaxACT. Maybe I did something wrong with TurboTax, but the refund was more in line with previous years. Certainly for my situation, TurboTax was clearly worth the price of admission.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/03/28/ok-maybe-turbotax-is-worth-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suppressing CA1062 with a Helper Function</title>
		<link>http://esmithy.net/2011/03/15/suppressing-ca1062/</link>
		<comments>http://esmithy.net/2011/03/15/suppressing-ca1062/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 04:32:36 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Visual Studio Tips]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=439</guid>
		<description><![CDATA[I think Visual Studio&#8217;s static analysis warning for checking parameters for null before they are used is generally a good idea, but the code to check the parameters can get really tedious. Before addressing the tedium, though, why does it even matter whether you check for null arguments and throw a ArgumentNullException? You&#8217;ll just get [...]]]></description>
			<content:encoded><![CDATA[<p>I think Visual Studio&#8217;s static analysis warning for checking parameters for null before they are used is generally a good idea, but the code to check the parameters can get really tedious.</p>
<p><span id="more-439"></span></p>
<p>Before addressing the tedium, though, why does it even matter whether you check for null arguments and throw a ArgumentNullException? You&#8217;ll just get a NullReferenceException if you don&#8217;t anyway. Is the ArgumentNullException somehow better?</p>
<p>The ArgumentNullException has a couple of benefits: It clearly indicates that the caller is to blame and by including the parameter name quickly narrows down the problem instead of requiring you to figure out which reference within the body of the method is null.</p>
<p>Although an ArgumentNullException is preferable, the null checking can overwhelm a short method. Here&#8217;s a contrived example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> PrintThings<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> things<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>things <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ArgumentNullException<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;things&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>var thing <span style="color: #0600FF; font-weight: bold;">in</span> things<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>thing<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Half the method is dedicated to checking the parameter for null. Now imagine if a relatively short method had three parameters to check. It would be all null checks and hardly any code.</p>
<p>In the spirit of conciseness, I&#8217;ve frequently had some kind of helper function that does the null check:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> PrintThings<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> things<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  Arg<span style="color: #008000;">.</span><span style="color: #0000FF;">NotNull</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;things&quot;</span>, things<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>var thing <span style="color: #0600FF; font-weight: bold;">in</span> things<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>thing<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The trouble is, Visual Studio&#8217;s static analysis doesn&#8217;t recognize this as a parameter validation of &#8220;things&#8221;, so you&#8217;ll get the CA1062 warning. </p>
<p>The work-around is to create a ValidatedNotNullAttribute and include it in the helper method, which signals to static analysis that, trust me, I really am checking the parameter. Here&#8217;s a complete example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> CA1062Test
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">class</span> Program
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            PrintThings<span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">&quot;one&quot;</span>, <span style="color: #666666;">&quot;two&quot;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> PrintThings<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> things<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            Arg<span style="color: #008000;">.</span><span style="color: #0000FF;">NotNull</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;things&quot;</span>, things<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>var thing <span style="color: #0600FF; font-weight: bold;">in</span> things<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>thing<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">class</span> Arg
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> NotNull<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> name, <span style="color: #008000;">&#91;</span>ValidatedNotNull<span style="color: #008000;">&#93;</span> <span style="color: #6666cc; font-weight: bold;">object</span> value<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>value <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ArgumentNullException<span style="color: #008000;">&#40;</span>name<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">sealed</span> <span style="color: #6666cc; font-weight: bold;">class</span> ValidatedNotNullAttribute <span style="color: #008000;">:</span> Attribute
    <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Notice the trivial ValidatedNotNullAttribute implementation &#8212; it doesn&#8217;t matter what it does so long as it is named &#8220;ValidatedNotNullAttribute&#8221;. The attribute is applied to the parameter being checked in the NotNull function, so it only has to be specified once in the helper declaration, and <strong>not</strong> on each use of the helper.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/03/15/suppressing-ca1062/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Evernote vs. OneNote</title>
		<link>http://esmithy.net/2011/03/05/evernote-vs-onenote/</link>
		<comments>http://esmithy.net/2011/03/05/evernote-vs-onenote/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 16:59:23 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=436</guid>
		<description><![CDATA[I&#8217;ve used both Evernote and Microsoft OneNote for several years. While there are lots of extensive comparisons of the applications around, I think the difference between them comes down to just a few broad issues. Evernote has these things going for it: Ubiquity Price (free) OneNote&#8217;s list is shorter: It&#8217;s a truly excellent Windows application [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve used both <a href="http://www.evernote.com/" target="_blank">Evernote</a> and <a href="http://office.microsoft.com/en-us/onenote/" target="_blank">Microsoft OneNote</a> for several years. While there are lots of extensive comparisons of the applications around, I think the difference between them comes down to just a few broad issues.<br />
<span id="more-436"></span><br />
Evernote has these things going for it:</p>
<ol>
<li>Ubiquity</li>
<li>Price (free)</li>
</ol>
<p>OneNote&#8217;s list is shorter:</p>
<ol>
<li>It&#8217;s a truly excellent Windows application</li>
</ol>
<p>The folks at Evernote can&#8217;t quite seem to get their act together. I think the Windows application has been through at least two complete rewrites since I&#8217;ve been using it, each time with the promise that <em>this</em> version will finally be the solid platform on which fantastic new features will be added. But the editing abilities still compare unfavorably to 1990&#8242;s-era HTML editors.</p>
<p>I can expect, though, that I&#8217;ll be able to find an Evernote client for pretty much any platform I want, with data synchronized between all of them because of Evernote&#8217;s cloud focus. Not all of the clients are created equal &#8212; Evernote for the iPad simply refuses to edit notes with &#8220;rich&#8221; formatting &#8212; but they aren&#8217;t bad.</p>
<p>OneNote&#8217;s anchor to Desktop Windows has been its biggest downfall. The cloud-stored notebooks of OneNote 2010 are a great advancement, but Microsoft needs clients for other platforms &#8212; and <em>good</em> clients at that. Even when I had a Windows Mobile phone a few years ago, the OneNote client there was pathetic. I regularly run Evernote clients on Windows, Mac, iOS (iPad) and webOS, and until I can do the same with OneNote, it&#8217;s hard to imagine it becoming my primary exocortex. That Microsoft has released an <a href="http://itunes.apple.com/us/app/microsoft-onenote/id410395246?mt=8" target="_blank">iPhone client</a> is promising. Hopefully they&#8217;ll continue to add other platforms.</p>
<p>Using OneNote on Windows is a delight. Formatting works as expected instead of suddenly flaking out like it does in Evernote. Tables are easy to work with and look good. Images can be resized in-line. Screen clips go into the note I&#8217;m editing instead of a separate note, which is the behavior I want 95% of the time.</p>
<p>That Evernote is free is nice, but I&#8217;ve got 80 bucks sitting right here for OneNote if it can make that final jump to universal access.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/03/05/evernote-vs-onenote/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Migrating from TFS to SVN</title>
		<link>http://esmithy.net/2011/02/01/migrating-from-tfs-to-svn/</link>
		<comments>http://esmithy.net/2011/02/01/migrating-from-tfs-to-svn/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 03:14:43 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://esmithy.net/?p=424</guid>
		<description><![CDATA[I&#8217;ve just spent the past few days migrating a Team Foundation Server source repository to Subversion. It took longer and was more difficult than I expected it to be. Of course, the easy way is to just get the latest from the TFS repository and add all of the files to the new SVN repository, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just spent the past few days migrating a Team Foundation Server source repository to Subversion. It took longer and was more difficult than I expected it to be.</p>
<p><span id="more-424"></span></p>
<p>Of course, the easy way is to just get the latest from the TFS repository and add all of the files to the new SVN repository, but change history is valuable and I didn&#8217;t want to:</p>
<ol>
<li>lose it</li>
<li>be required to go back to TFS to get it</li>
</ol>
<p>I found <a href="http://sourceforge.net/projects/tfs2svn/">tfs2svn</a>, a tool written by Kevin Colyar expressly for the purpose of migrating while preserving the change history. If you&#8217;re going to run this on a big, mature TFS repository, there are a couple of things you should know:</p>
<ol>
<li>It&#8217;s going to take a long time.</li>
<li>Stuff is going to go wrong.</li>
</ol>
<p>This is no disrespect to Kevin &#8212; that the tool is available at all is a great help. I also have to confess that I hacked the source code a bit, so there&#8217;s a possibility that some of what went wrong was my own fault.</p>
<h3>My Scenario</h3>
<p>The repository I migrated has about five and a half years of history, comprised of nearly 21,000 changesets. It also had code from several projects, and I really only wanted to migrate a subset of the tree. We already have a Subversion repository with some source in it, so I wanted to get the TFS source into there.</p>
<h3>Strategy</h3>
<p>My plan was to create a local, temporary Subversion repository into which I could do the conversion. This would let me mess up in various spectacular ways without risk to the real SVN repository that would be the code&#8217;s ultimate home. It also seemed like it would be faster than running all of the SVN commands across the network to the Subversion server. Once the migration was done locally, I&#8217;d use <strong>svnadmin dump</strong> to generate a version of the repository that could be imported into the &#8220;real&#8221; repository with <strong>svnadmin load</strong>.</p>
<p>I hoped that I&#8217;d be able to use tfs2svn to limit the migration to only the parts of the tree that I wanted, but the tool resisted my attempts to do so. I was thinking that I&#8217;d run it multiple times, changing the paths to get one relevant top-level  folder at a time. It&#8217;s not clear which path to change, though. You&#8217;ve got the TFS repository path (which would be a must), the SVN repository path and the SVN working copy path. It turns out that all of those paths are used in different situations by the tool, and I eventually thought it might be best to just migrate the whole thing.</p>
<p>It would be tragic to actually include everything in the final SVN repository, though, given that Subversion doesn&#8217;t have a permanent delete feature (that is, &#8220;obliterate&#8221;). All the stuff I didn&#8217;t want to migrate would be forever in the repository. But since I was going to do a dump anyway, I could run <strong>dumpfilter</strong> to remove the stuff I didn&#8217;t want.</p>
<p>The trouble then becomes time. It takes so long to migrate all those TFS changesets into SVN that I very quickly decided I needed to push the filtering forward in the process. This is where the hacking began.</p>
<p>I added a &#8220;IncludeChange&#8221; check into TfsClientProvider&#8217;s ProcessChange method:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ProcessChange<span style="color: #008000;">&#40;</span>Changeset changeset, Change change<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
          <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>IncludeChange<span style="color: #008000;">&#40;</span>change<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#123;</span>
              <span style="color: #008080; font-style: italic;">// Process file change.</span>
              <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>change<span style="color: #008000;">.</span><span style="color: #0000FF;">Item</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ItemType</span> <span style="color: #008000;">==</span> ItemType<span style="color: #008000;">.</span><span style="color: #0000FF;">File</span><span style="color: #008000;">&#41;</span>
                  ProcessFileChange<span style="color: #008000;">&#40;</span>changeset, change<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
              <span style="color: #008080; font-style: italic;">// Process folder change.</span>
              <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>change<span style="color: #008000;">.</span><span style="color: #0000FF;">Item</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ItemType</span> <span style="color: #008000;">==</span> ItemType<span style="color: #008000;">.</span><span style="color: #0000FF;">Folder</span><span style="color: #008000;">&#41;</span>
                  ProcessFolderChange<span style="color: #008000;">&#40;</span>changeset, change<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
              <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
          <span style="color: #008000;">&#125;</span>
          <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span></pre></div></div>

<p>IncludeChange has a bunch of lines that look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>change<span style="color: #008000;">.</span><span style="color: #0000FF;">Item</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ServerItem</span><span style="color: #008000;">.</span><span style="color: #0000FF;">StartsWith</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;$/Projects/Main/Applications&quot;</span>, StringComparison<span style="color: #008000;">.</span><span style="color: #0000FF;">OrdinalIgnoreCase</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span></pre></div></div>

<p>This combination skips any changes that were in areas that I didn&#8217;t care about. ProcessChange also now returns a boolean to indicate whether anything from the changeset needs to be committed in Subversion, saving additional time by skipping an unneeded operation.</p>
<h3>Problems</h3>
<p>One of the really good things about tfs2svn is the Start at Changeset# field. When something goes wrong, you can always start back up where you left off &#8212; even if you have to exit the program. Sometimes tfs2svn will even offer to fill in the Start at Changeset# field for you when it&#8217;s about to report an error.</p>
<p>These are some of the things that went wrong.</p>
<p>At first I was getting an obscure <em>Error resolving case of</em> [some path]. Hard to figure out, but easy to fix: I just needed to take the trailing backslash off the Working copy folder.</p>
<p>I also ran into a problem when a changeset moved some files from a place that I was excluding to a place that I wasn&#8217;t excluding. That didn&#8217;t turn out so well since the source files didn&#8217;t exist, having been skipped by my IncludeChange method. This was fairly early on, so I just decided to start over and not exclude the source path. I might have been able to get a copy of the files and add them to SVN in the appropriate place and retry, though.</p>
<p>Directory deletes in TFS frequently caused trouble in the conversion. They would result in an unresolved conflict on the directory and the commit would fail. In these cases, I just marked the conflict resolved, committed manually and skipped to the next changeset. You lose some of the history in these cases by doing that, though.</p>
<p>Directory adds also caused troubles at times. The tool would try to add a file to a directory that hadn&#8217;t been created yet. To fix those, I just created the directory by hand and added it to SVN and retried the problematic changeset.</p>
<p>There was one situation where some file renames weren&#8217;t working at all. The original files didn&#8217;t exist and the destination files did. I kind of mangled that changeset, but fortunately I knew that those files were obsolete and would all be deleted in a later changeset, so I didn&#8217;t care much about them anyway. I think this was probably caused by a situation where part of a changeset had been processed, but then there was an error. Retrying the changeset meant it tried to redo some moves that were already done.</p>
<p>Finally, there were some times when the network would timeout, or Subversion would report that a file or directory was corrupt or unreadable. In those cases, I just tried again and was always successful the next time.</p>
<p>With these errors popping up, tfs2svn required a lot of babysitting to notice the error, make a fix and get it going again. That unfortunately added to the total time span since it would invariably stop when you were busy with something else, or when you hoped to make good progress letting it run overnight.</p>
<h3>Finish</h3>
<p>Once the migration was done, <strong>svnadmin dump</strong> was relatively quick and completely painless. Once I could get some of IT&#8217;s time (someone with direct access to the Subversion server), the load also was quick and easy.</p>
<h3>Update (4 Feb 2011)</h3>
<p>I&#8217;ve noticed another problem in the migrated history. Sometimes the author of a change seems to be incorrect. According to the history, a developer from another team did some work that would be extremely unlikely if it were true. I haven&#8217;t figured this one out yet&#8230;</p>
<h3>Update (22 Mar 2011)</h3>
<p>A possible explanation for the &#8220;The file or directory is corrupted and unreadable&#8221; errors is a <a href="http://social.technet.microsoft.com/Forums/en/w7itprogeneral/thread/df935a52-a0a9-4f67-ac82-bc39e0585148">bug in Windows 7</a>. The bug fix is included in Windows 7 SP1, which you can get through Windows Update.</p>
]]></content:encoded>
			<wfw:commentRss>http://esmithy.net/2011/02/01/migrating-from-tfs-to-svn/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

