<?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>Ted Naleid &#187; shortcut</title>
	<atom:link href="http://naleid.com/blog/category/shortcut/feed/" rel="self" type="application/rss+xml" />
	<link>http://naleid.com/blog</link>
	<description>Groovy, Grails and OS X tips and tricks</description>
	<lastBuildDate>Wed, 16 May 2012 00:54:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Quick Shell Function to Bootstrap a Gradle Groovy Project</title>
		<link>http://naleid.com/blog/2012/02/29/quick-shell-function-to-bootstrap-a-gradle-groovy-project/</link>
		<comments>http://naleid.com/blog/2012/02/29/quick-shell-function-to-bootstrap-a-gradle-groovy-project/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 03:57:39 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=571</guid>
		<description><![CDATA[Gradle is a great build tool. It&#8217;s easy to download and install. If you&#8217;re on a mac and have homebrew, it&#8217;s as easy as: brew install gradle It&#8217;s very easy to use with a little experience, but I find having a good starting place to base your work from can help. Here&#8217;s a quick function [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://gradle.org/" onclick="pageTracker._trackPageview('/outgoing/gradle.org/?referer=');">Gradle</a> is a great build tool.  It&#8217;s easy to <a href="http://gradle.org/downloads" onclick="pageTracker._trackPageview('/outgoing/gradle.org/downloads?referer=');">download</a> and install.  If you&#8217;re on a mac and have <a href="http://mxcl.github.com/homebrew/" onclick="pageTracker._trackPageview('/outgoing/mxcl.github.com/homebrew/?referer=');">homebrew</a>, it&#8217;s as easy as:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">brew <span style="color: #c20cb9; font-weight: bold;">install</span> gradle</pre></div></div>

<p>It&#8217;s very easy to use with a little experience, but I find having a good starting place to base your work from can help.</p>
<p>Here&#8217;s a quick function that I&#8217;ve got in my <code>.zshrc</code> to bootstrap a new groovy gradle project in the current directory (it should also work in in a .profile/.bash_profile/.bashrc).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> newgradle<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Creating files for new gradle project&quot;</span>
&nbsp;
    <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;&lt;</span>EOF<span style="color: #000000; font-weight: bold;">&gt;</span>.gitignore
<span style="color: #000000; font-weight: bold;">*</span>.un~
<span style="color: #000000; font-weight: bold;">*</span>.iml
<span style="color: #000000; font-weight: bold;">*</span>.ipr
<span style="color: #000000; font-weight: bold;">*</span>.iws
build
.gradle
EOF
&nbsp;
    <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;&lt;</span>EOF<span style="color: #000000; font-weight: bold;">&gt;</span>build.gradle
apply plugin: <span style="color: #ff0000;">'groovy'</span>
apply plugin: <span style="color: #ff0000;">'idea'</span>
&nbsp;
repositories <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    mavenCentral<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
dependencies <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    groovy <span style="color: #ff0000;">'org.codehaus.groovy:groovy-all:1.8.6'</span>
    groovy <span style="color: #ff0000;">'org.apache.ivy:ivy:2.2.0'</span>
    testCompile <span style="color: #ff0000;">'junit:junit:4.10'</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
task createSourceDirs<span style="color: #7a0874; font-weight: bold;">&#40;</span>description : <span style="color: #ff0000;">'Create empty source directories for all defined sourceSets'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    sourceSets<span style="color: #000000; font-weight: bold;">*</span>.allSource.srcDirs.flatten<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>.each <span style="color: #7a0874; font-weight: bold;">&#123;</span> File sourceDirectory -<span style="color: #000000; font-weight: bold;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">!</span>sourceDirectory.exists<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
            println <span style="color: #ff0000;">&quot;Making <span style="color: #000099; font-weight: bold;">\$</span>sourceDirectory&quot;</span>
            sourceDirectory.mkdirs<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
    <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
idea <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    project <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        jdkName = <span style="color: #ff0000;">'1.6'</span>
    <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
EOF
&nbsp;
    gradle createSourceDirs
&nbsp;
    <span style="color: #c20cb9; font-weight: bold;">git</span> init
    <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-a1</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">find</span> src    <span style="color: #666666; font-style: italic;"># list all created assets</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>It creates a <code>build.gradle</code> file ready to work with java and groovy projects, including IDEA integration (just execute <code>gradle idea</code>).</p>
<p>This gives you all of the tasks necessary to compile, jar, test, and distribute your code.  For more information, check out the gradle docs on the <a href="http://gradle.org/docs/current/userguide/java_plugin.html" onclick="pageTracker._trackPageview('/outgoing/gradle.org/docs/current/userguide/java_plugin.html?referer=');">java</a>, <a href="http://gradle.org/docs/current/userguide/groovy_plugin.html" onclick="pageTracker._trackPageview('/outgoing/gradle.org/docs/current/userguide/groovy_plugin.html?referer=');">groovy</a>, and <a href="http://gradle.org/docs/current/userguide/idea_plugin.html" onclick="pageTracker._trackPageview('/outgoing/gradle.org/docs/current/userguide/idea_plugin.html?referer=');">idea</a> tasks.</p>
<p>It also creates all the necessary source directories for you and initializes a new git repository (with starting <code>.gitignore</code> file) for you to save your work.</p>
<p>You can easily tweak the <code>build.gradle</code> or <code>.gitignore</code> files to fit your needs.  If you don&#8217;t use git, you can either delete those lines, or subsitute the equivalent lines for the source control tool you use. These are just a good starting place for me.</p>
<p>Here&#8217;s the sample output from the script above:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> testapp
<span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">cd</span> testapp
<span style="color: #000000; font-weight: bold;">%</span> newgradle                                                                   
Creating files <span style="color: #000000; font-weight: bold;">for</span> new gradle project
:createSourceDirs
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>resources
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>java
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>groovy
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>resources
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>java
Making <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>groovy
&nbsp;
BUILD SUCCESSFUL
&nbsp;
Total <span style="color: #000000; font-weight: bold;">time</span>: <span style="color: #000000;">2.344</span> secs
Initialized empty Git repository <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>tnaleid<span style="color: #000000; font-weight: bold;">/</span>Documents<span style="color: #000000; font-weight: bold;">/</span>workspace<span style="color: #000000; font-weight: bold;">/</span>testapp<span style="color: #000000; font-weight: bold;">/</span>.git<span style="color: #000000; font-weight: bold;">/</span>
.
..
.git
.gitignore
.gradle
build.gradle
src
src
src<span style="color: #000000; font-weight: bold;">/</span>main
src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>groovy
src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>java
src<span style="color: #000000; font-weight: bold;">/</span>main<span style="color: #000000; font-weight: bold;">/</span>resources
src<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span>
src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>groovy
src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>java
src<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>resources</pre></div></div>

<p>Then you&#8217;ve got all this gradle functionality ready to use:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> gradle tasks                                                           
:tasks
&nbsp;
<span style="color: #660033;">------------------------------------------------------------</span>
All tasks runnable from root project
<span style="color: #660033;">------------------------------------------------------------</span>
&nbsp;
Build tasks
<span style="color: #660033;">-----------</span>
assemble - Assembles all Jar, War, Zip, and Tar archives.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles the main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles the <span style="color: #7a0874; font-weight: bold;">test</span> classes.
&nbsp;
Documentation tasks
<span style="color: #660033;">-------------------</span>
groovydoc - Generates Groovydoc API documentation <span style="color: #000000; font-weight: bold;">for</span> the main <span style="color: #7a0874; font-weight: bold;">source</span> code.
javadoc - Generates Javadoc API documentation <span style="color: #000000; font-weight: bold;">for</span> the main <span style="color: #7a0874; font-weight: bold;">source</span> code.
&nbsp;
Help tasks
<span style="color: #660033;">----------</span>
dependencies - Displays the dependencies of root project <span style="color: #ff0000;">'test'</span>.
<span style="color: #7a0874; font-weight: bold;">help</span> - Displays a <span style="color: #7a0874; font-weight: bold;">help</span> message
projects - Displays the sub-projects of root project <span style="color: #ff0000;">'test'</span>.
properties - Displays the properties of root project <span style="color: #ff0000;">'test'</span>.
tasks - Displays the tasks runnable from root project <span style="color: #ff0000;">'test'</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>some of the displayed tasks may belong to subprojects<span style="color: #7a0874; font-weight: bold;">&#41;</span>.
&nbsp;
IDE tasks
<span style="color: #660033;">---------</span>
cleanIdea - Cleans IDEA project files <span style="color: #7a0874; font-weight: bold;">&#40;</span>IML, IPR<span style="color: #7a0874; font-weight: bold;">&#41;</span>
idea - Generates IDEA project files <span style="color: #7a0874; font-weight: bold;">&#40;</span>IML, IPR, IWS<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
Verification tasks
<span style="color: #660033;">------------------</span>
check - Runs all checks.
<span style="color: #7a0874; font-weight: bold;">test</span> - Runs the unit tests.
&nbsp;
Other tasks
<span style="color: #660033;">-----------</span>
cleanIdeaWorkspace
createSourceDirs - Create empty <span style="color: #7a0874; font-weight: bold;">source</span> directories <span style="color: #000000; font-weight: bold;">for</span> all defined sourceSets
&nbsp;
Rules
<span style="color: #660033;">-----</span>
Pattern: build<span style="color: #000000; font-weight: bold;">&lt;</span>ConfigurationName<span style="color: #000000; font-weight: bold;">&gt;</span>: Assembles the artifacts of a configuration.
Pattern: upload<span style="color: #000000; font-weight: bold;">&lt;</span>ConfigurationName<span style="color: #000000; font-weight: bold;">&gt;</span>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean<span style="color: #000000; font-weight: bold;">&lt;</span>TaskName<span style="color: #000000; font-weight: bold;">&gt;</span>: Cleans the output files of a task.
&nbsp;
To see all tasks and <span style="color: #c20cb9; font-weight: bold;">more</span> detail, run with --all.
&nbsp;
BUILD SUCCESSFUL
&nbsp;
Total <span style="color: #000000; font-weight: bold;">time</span>: <span style="color: #000000;">4.871</span> secs</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2012/02/29/quick-shell-function-to-bootstrap-a-gradle-groovy-project/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Finding and Purging Big Files From Git History</title>
		<link>http://naleid.com/blog/2012/01/17/finding-and-purging-big-files-from-git-history/</link>
		<comments>http://naleid.com/blog/2012/01/17/finding-and-purging-big-files-from-git-history/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 06:58:13 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=566</guid>
		<description><![CDATA[On a recent grails project, we&#8217;re using a git repo that was originally converted from a SVN repo with a ton of large binary objects in it (lots of jar files that really should come from an ivy/maven repo). The .git directory was over a gigabyte in size and this made it very cumbersome to [...]]]></description>
			<content:encoded><![CDATA[<p>On a recent grails project, we&#8217;re using a git repo that was originally converted from a SVN repo with a ton of large binary objects in it (lots of jar files that really should come from an ivy/maven repo).  The <code>.git</code> directory was over a gigabyte in size and this made it very cumbersome to clone and manipulate.</p>
<p>We decided to leverage git&#8217;s history rewriting capabilities to make a much smaller repository (and kept our previous repo as a backup just in case).</p>
<p>Here are a few questions/answers that I figured out how to answer with git and some shell commands:</p>
<h4>What object SHA is associated with each file in the Repo?</h4>
<p>Git has a unique SHA that it associates with each object (such as files which it calls blobs) throughout it&#8217;s history.</p>
<p>This helps us find that object and decide whether it&#8217;s worth deleting later on:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> rev-list <span style="color: #660033;">--objects</span> <span style="color: #660033;">--all</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-k</span> <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">&gt;</span> allfileshas.txt</pre></div></div>

<p>Take a look at the resulting <code>allfileshas.txt</code> file for the full list.  </p>
<h4>What Unique Files Exist Throughout The History of My Git Repo?</h4>
<p>If you want to see the unique files throughout the history of your git repo (such as to grep for .jar files that you might have committed a while ago):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">    <span style="color: #c20cb9; font-weight: bold;">git</span> rev-list <span style="color: #660033;">--objects</span> <span style="color: #660033;">--all</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-k</span> <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-f</span> <span style="color: #000000;">2</span> -d\  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">uniq</span></pre></div></div>

<h4>How Big Are The Files In My Repo?</h4>
<p>We can find the big files in our repo by doing a <code>git gc</code> which makes git compact the archive and stores an index file that we can analyse.</p>
<p>Get the last object SHA for all committed files and sort them in biggest to smallest order:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">gc</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">git</span> verify-pack <span style="color: #660033;">-v</span> .git<span style="color: #000000; font-weight: bold;">/</span>objects<span style="color: #000000; font-weight: bold;">/</span>pack<span style="color: #000000; font-weight: bold;">/</span>pack-<span style="color: #000000; font-weight: bold;">*</span>.idx <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #ff0000;">&quot;^\w+ blob\W+[0-9]+ [0-9]+ [0-9]+$&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-k</span> <span style="color: #000000;">3</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">&gt;</span> bigobjects.txt</pre></div></div>

<p>Take that result and iterate through each line of it to find the SHA, file size in bytes, and real file name (you also need the allfileshas.txt output file from above):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">for</span> SHA <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-f</span> <span style="color: #000000;">1</span> -d\  <span style="color: #000000; font-weight: bold;">&lt;</span> bigobjects.txt<span style="color: #000000; font-weight: bold;">`</span>; <span style="color: #000000; font-weight: bold;">do</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #007800;">$SHA</span> bigobjects.txt<span style="color: #7a0874; font-weight: bold;">&#41;</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #007800;">$SHA</span> allfileshas.txt<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1,$3,$7}'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> bigtosmall.txt
<span style="color: #000000; font-weight: bold;">done</span>;</pre></div></div>

<p>(there&#8217;s probably a more efficient way to do this, but this was fast enough for my purposes with ~50k files in our repo)</p>
<p>Then, just take a look at the bigtosmall.txt file to see your biggest file culprits.</p>
<h4>Purging a file or directory from history</h4>
<p>Use filter-branch to remove the file/directory (replace <code>MY-BIG-DIRECTORY-OR-FILE</code> with the path that you&#8217;d like to delete relative to the root of the git repo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> filter-branch <span style="color: #660033;">--prune-empty</span> <span style="color: #660033;">--index-filter</span> <span style="color: #ff0000;">'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE'</span> <span style="color: #660033;">--tag-name-filter</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #660033;">--</span> <span style="color: #660033;">--all</span></pre></div></div>

<p>Then clone the repo and make sure to not leave any hard links with:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #660033;">--no-hardlinks</span> <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>yourUser<span style="color: #000000; font-weight: bold;">/</span>your<span style="color: #000000; font-weight: bold;">/</span>full<span style="color: #000000; font-weight: bold;">/</span>repo<span style="color: #000000; font-weight: bold;">/</span>path repo-clone-name</pre></div></div>

<p>You can use this command from the parent directory that contains your git repository and it&#8217;s clone to see how much space each of them take, and how much you&#8217;ve shrunk the repo in size:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">du</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>     <span style="color: #666666; font-style: italic;"># add the -h flag to see the output in human readable size formats, just like ls -lah vs ls -la</span></pre></div></div>

<p>With these commands, I was able to reduce the file size of our repo with a few thousand commits down below the size of the checked out repository (more than an order of magnitude smaller).  I only removed old binary files, we still have full history for all code files.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2012/01/17/finding-and-purging-big-files-from-git-history/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to use kdiff3 as a 3-way merge tool with mercurial, git, and Tower.app</title>
		<link>http://naleid.com/blog/2012/01/12/how-to-use-kdiff3-as-a-3-way-merge-tool-with-mercurial-git-and-tower-app/</link>
		<comments>http://naleid.com/blog/2012/01/12/how-to-use-kdiff3-as-a-3-way-merge-tool-with-mercurial-git-and-tower-app/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 06:29:08 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=523</guid>
		<description><![CDATA[There are a few very nice looking, mac-like diff tools for OSX (Kaleidoscope and Changes come to mind), but none for doing &#8220;real&#8221; merges. By this, I mean real, 3-way merges with all of the information you need in front of you. There are no good-looking, &#8220;mac-like&#8221; merge tools, but if you swallow your pride [...]]]></description>
			<content:encoded><![CDATA[<p>There are a few very nice looking, mac-like diff tools for OSX (<a href="http://www.kaleidoscopeapp.com/" onclick="pageTracker._trackPageview('/outgoing/www.kaleidoscopeapp.com/?referer=');">Kaleidoscope</a> and <a href="http://connectedflow.com/changes/" onclick="pageTracker._trackPageview('/outgoing/connectedflow.com/changes/?referer=');">Changes</a> come to mind), but none for doing &#8220;real&#8221; merges.  By this, I mean real, <a href="http://en.wikipedia.org/wiki/3-way_merge#Three-way_merge" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/3-way_merge_Three-way_merge?referer=');">3-way merges</a> with all of the information you need in front of you.</p>
<p>There are no good-looking, &#8220;mac-like&#8221; merge tools, but if you swallow your pride there are a few different options for 3-way merges, including <a href="http://www.araxis.com/merge_mac/" onclick="pageTracker._trackPageview('/outgoing/www.araxis.com/merge_mac/?referer=');">Araxis Merge ($$$!)</a>, <a href="http://www.sourcegear.com/diffmerge/downloads.php" onclick="pageTracker._trackPageview('/outgoing/www.sourcegear.com/diffmerge/downloads.php?referer=');">DiffMerge</a>, <a href="http://www.deltopia.com/compare-merge-sync/macosx/" onclick="pageTracker._trackPageview('/outgoing/www.deltopia.com/compare-merge-sync/macosx/?referer=');">DeltaWalker</a>, and <a href="http://en.wikipedia.org/wiki/Apple_Developer_Tools#FileMerge" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Apple_Developer_Tools_FileMerge?referer=');">FileMerge</a> which comes free with XCode.</p>
<p>I&#8217;ve tried them all, and find them all confusing.  They all tend use a 3-pane display to do the merging with your file in the left pane, the file you&#8217;re merging in the right pane, and the messy half-merged file in the middle.</p>
<p>That&#8217;s not enough information.</p>
<p>A 3-way merge actually has four important sources of information:<span id="more-523"></span></p>
<ul>
<li><code>LOCAL</code> &#8211; your file with the changes you&#8217;ve made to it</li>
<li><code>REMOTE</code> &#8211; the file you&#8217;re merging in, possibly authored by someone else</li>
<li><code>BASE</code> &#8211; the common ancestor file that <code>LOCAL</code> and <code>REMOTE</code> came from</li>
<li><code>MERGE_RESULT</code> &#8211; the file resulting from the merge where you resolve conflicts</li>
</ul>
<p>You often need to see all four of these pieces of information to make intelligent choices.  Where you came from (<code>LOCAL</code>), where the other person&#8217;s changes came from (<code>REMOTE</code>), where you both started (<code>BASE</code>) and where you are now (<code>MERGE_RESULT</code>).</p>
<p>Most other 3-way merge tools either conflate or omit the <code>BASE</code> and that can make it harder to see what the right thing to do is.</p>
<p><a href="http://kdiff3.sourceforge.net/" onclick="pageTracker._trackPageview('/outgoing/kdiff3.sourceforge.net/?referer=');">Kdiff3</a> is my merge tool of choice.  It&#8217;s not pretty; it&#8217;s cross-platform <a href="http://en.wikipedia.org/wiki/Qt_(framework)" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Qt_framework?referer=');">Qt</a> based so it has a very old-school linux GUI feel to it.  But like linux, it&#8217;s functional and can help you quickly be productive once you get over the learning curve.</p>
<p>If you&#8217;ve got 2 heads that you need to merge in your current repository:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/2_heads_need_to_merge.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/2_heads_need_to_merge.png" alt="" title="2_heads_need_to_merge" width="403" height="107" class="aligncenter size-full wp-image-526" /></a><br />
We made this modification to <code>file.txt</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">diff</span> <span style="color: #660033;">--git</span> a<span style="color: #000000; font-weight: bold;">/</span>file.txt b<span style="color: #000000; font-weight: bold;">/</span>file.txt
<span style="color: #660033;">---</span> a<span style="color: #000000; font-weight: bold;">/</span>file.txt
+++ b<span style="color: #000000; font-weight: bold;">/</span>file.txt
<span style="color: #000000; font-weight: bold;">@@</span> -<span style="color: #000000;">1</span>,<span style="color: #000000;">1</span> +<span style="color: #000000;">1</span>,<span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">@@</span>
-BASE: common_ancestor
+LOCAL: <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">in</span> current working branch</pre></div></div>

<p>and they made this change to the same file and line:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">diff</span> <span style="color: #660033;">--git</span> a<span style="color: #000000; font-weight: bold;">/</span>file.txt b<span style="color: #000000; font-weight: bold;">/</span>file.txt
<span style="color: #660033;">---</span> a<span style="color: #000000; font-weight: bold;">/</span>file.txt
+++ b<span style="color: #000000; font-weight: bold;">/</span>file.txt
<span style="color: #000000; font-weight: bold;">@@</span> -<span style="color: #000000;">1</span>,<span style="color: #000000;">1</span> +<span style="color: #000000;">1</span>,<span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">@@</span>
-BASE: common_ancestor
+REMOTE: other branch we<span style="color: #ff0000;">'re merging in</span></pre></div></div>

<p>If you run your SCM&#8217;s merge command (here, in mercurial: <code>hg merge -r 2</code>), and have kdiff3 configured as your merge tool, you&#8217;ll get a pop-up window like this:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/kdiff3_merge_window_fixed.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/kdiff3_merge_window_fixed.png" alt="" title="kdiff3_merge_window_fixed" width="1241" height="512" class="alignleft size-full wp-image-555" /></a><br />
As you can see, it shows you all 4 pieces of information, <code>BASE</code>, <code>LOCAL</code>, and <code>REMOTE</code> on top, and the <code>MERGE_RESULT</code> file on the bottom.  It currently has a <code>Merge Conflict</code> that you need to fix.</p>
<p>You can move from one unresolved conflict to the next using the triple up and triple-down colored arrows in the middle of the tool bar.  When a conflict is highlighted, you can press any combination of the A, B, and C buttons in the toolbar.  Pressing one of those buttons will resolve the conflict with the code from pane A, B, or C on top.  So if the <code>LOCAL</code> file (your file) had the right changes in it, you&#8217;d press B.</p>
<p>It&#8217;s possible to press more than one button if code from multiple panes is valid.  You can also directly edit the file in the <code>MERGE_RESULT</code> pane to make manual changes if the correct merge is not the exact text in A/B/C.</p>
<p>Another option, if you want to take all of the changes from one file and discard any changes from the others, is to go to the &#8220;Merge&#8221; menu and pick one of &#8220;Choose A Everywhere&#8221;, &#8220;Choose B Everywhere&#8221;, or &#8220;Choose C Everywhere&#8221;.</p>
<p>Once you&#8217;ve resolved your file, simply save it (cmd-S) and quit out of kdiff3.  Your SCM should see the <code>MERGE_RESULT</code> no longer has any merge conflicts and will mark it as resolved, ready for you to commit it.  If there are other files with merge conflicts, you can repeat the process with those files.</p>
<h2>Installing kdiff3</h2>
<p>Installing kdiff3 is as easy as <a href="http://sourceforge.net/projects/kdiff3/files/kdiff3/" onclick="pageTracker._trackPageview('/outgoing/sourceforge.net/projects/kdiff3/files/kdiff3/?referer=');">downloading the latest version from sourceforge</a> and copying it to your <code>/Applications</code> directory.</p>
<p>The app is a simple wrapper around a Qt-based application.  It can be run from the command line at <code>/Applications/kdiff3.app/Contents/MacOS/kdiff3</code>.  You can make a symlink of that into your path, but I assume in the instructions below only that you&#8217;ve got kdiff3 in your <code>/Applications</code> folder.</p>
<h2>Mercurial Integration</h2>
<p>Mercurial command line integration is pretty easy.  Just open up your <code>~/.hgrc</code> file (or create one if you don&#8217;t have it already), and add this to it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>extdiff<span style="color: #7a0874; font-weight: bold;">&#93;</span>
cmd.kdiff3 = <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>kdiff3.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<span style="color: #000000; font-weight: bold;">/</span>kdiff3
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>merge-tools<span style="color: #7a0874; font-weight: bold;">&#93;</span>
kdiff3.args = <span style="color: #007800;">$base</span> <span style="color: #007800;">$local</span> <span style="color: #007800;">$other</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">$output</span></pre></div></div>

<p>That configures kdiff3 as your merge tool of choice, so it should pop up automatically when you hit a merge conflict.  You can also use it as a diff tool:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg kdiff3 <span style="color: #660033;">-r</span> revision_to_compare_to</pre></div></div>

<h2>Git Command-Line Integration</h2>
<p>To configure the git command line to use kdiff3 as a diff and merge tool, add this to your ~/.gitconfig:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>difftool <span style="color: #ff0000;">&quot;kdiff3&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
    path = <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>kdiff3.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<span style="color: #000000; font-weight: bold;">/</span>kdiff3
    trustExitCode = <span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>difftool<span style="color: #7a0874; font-weight: bold;">&#93;</span>
    prompt = <span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #c20cb9; font-weight: bold;">diff</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
    tool = kdiff3
<span style="color: #7a0874; font-weight: bold;">&#91;</span>mergetool <span style="color: #ff0000;">&quot;kdiff3&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
    path = <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>kdiff3.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<span style="color: #000000; font-weight: bold;">/</span>kdiff3
    trustExitCode = <span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>mergetool<span style="color: #7a0874; font-weight: bold;">&#93;</span>
    keepBackup = <span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>merge<span style="color: #7a0874; font-weight: bold;">&#93;</span>
    tool = kdiff3</pre></div></div>

<p>Now you can use the external tool commands to look at diffs:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> difftool <span style="color: #7a0874; font-weight: bold;">&#91;</span>revision_sha<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>and fix unresolved merge conflicts:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> mergetool</pre></div></div>

<h2>Git Tower Integration</h2>
<p>I&#8217;m normally a pretty hard-core command line user, but I still sometimes find the places I get myself in git confusing enough that I&#8217;m willing to use a GUI to get myself out.  I think that <a href="http://www.git-tower.com/" onclick="pageTracker._trackPageview('/outgoing/www.git-tower.com/?referer=');">git-tower</a> is the best git GUI available right now. </p>
<p>It can show you diff files and lets you browse through history in it&#8217;s UI. It also lets you do a number of basic and mid-level commands (adding, committing, rebasing, squashing commits, cherry-picking, etc), but it doesn&#8217;t have a built-in diff or merge tool.  </p>
<p>It does come with the ability to integrate with a few different merge tools out of the box, but not kdiff3.  </p>
<p>After a little digging around, I found a generic <a href="http://www.git-tower.com/files/applicationHelp/pgs/Integration_DiffTools.html" onclick="pageTracker._trackPageview('/outgoing/www.git-tower.com/files/applicationHelp/pgs/Integration_DiffTools.html?referer=');">post showing how configure Tower with a plist file and a shim shell script</a>, but nothing specific to kdiff3.</p>
<p>I figured out how to get Tower and kdiff3 to play nice with each other, and have the instructions and files in a <a href="https://github.com/tednaleid/git-tower-kdiff3-shim" onclick="pageTracker._trackPageview('/outgoing/github.com/tednaleid/git-tower-kdiff3-shim?referer=');">GitHub repository</a>.  To get it working, just clone the repository to a temporary directory, and run the install.sh script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>tmp
<span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>github.com:tednaleid<span style="color: #000000; font-weight: bold;">/</span>git-tower-kdiff3-shim.git 
<span style="color: #7a0874; font-weight: bold;">cd</span> git-tower-kdiff3-shim
.<span style="color: #000000; font-weight: bold;">/</span>install.sh</pre></div></div>

<p>It simply copies the plist file and the shim script into the appropriate directories (and Tower is <i>very</i> picky about those locations).</p>
<p>Then you need to go into Tower&#8217;s Preferences->Git Config control panel, and choose kdiff3 as the diff and merge tool:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/tower_preferences.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/tower_preferences.png" alt="" title="tower_preferences" width="764" height="386" class="alignleft size-full wp-image-542" /></a><br />
For a quick rundown of how Tower works with kdiff3 as a merge tool, here&#8217;s an example where we&#8217;ve got one commit where we made changes to locally:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/my_master.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/my_master.png" alt="" title="my_master" width="1416" height="822" class="alignleft size-full wp-image-534" /></a><br />
And another commit on <code>origin/master</code> where someone else made changes to the same piece of code:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/their_master.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/their_master.png" alt="" title="their_master" width="1416" height="822" class="alignleft size-full wp-image-536" /></a><br />
We&#8217;ve pulled it down and now have 2 heads within our repository. To fix this, we need to merge and resolve the conflicts, hit the merge button and we&#8217;ll get an error message because there are conflicts that git can&#8217;t resolve automatically:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/tower-conflict.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/tower-conflict.png" alt="" title="tower-conflict" width="1416" height="822" class="alignleft size-full wp-image-540" /></a><br />
If you highlight a file with merge conflicts, and then hit the &#8220;Merge Tool&#8221; button, it will bring up kdiff3 and let us use it to resolve the issue:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/kdiff3-merge.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/kdiff3-merge.png" alt="" title="kdiff3-merge" width="1257" height="512" class="alignleft size-full wp-image-545" /></a><br />
Fix the merge conflicts in kdiff3 (ex: press &#8220;C&#8221; to change it to &#8220;Goodbye Cruel World&#8221;), save it, and quit out of kdiff3. Tower should see that the file has had it&#8217;s conflicts resolved and lets you commit the merge and carry on.</p>
<p>You can also use Kdiff3 as a regular diff tool if you don&#8217;t like looking at diff files.  Just choose a file that you&#8217;ve modified to diff:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/tower-diff.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/tower-diff.png" alt="" title="tower-diff" width="1416" height="822" class="alignleft size-full wp-image-547" /></a><br />
Press the &#8220;Diff Tool&#8221; button, and it&#8217;ll pop up in kdiff3:<br />
<a href="http://naleid.com/blog/wp-content/uploads/2012/01/tower-kdiff3.png"><img src="http://naleid.com/blog/wp-content/uploads/2012/01/tower-kdiff3.png" alt="" title="tower-kdiff3" width="1257" height="512" class="alignleft size-full wp-image-548" /></a><br />
Kdiff3 might be homely, but it&#8217;s easy to use once you understand how it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2012/01/12/how-to-use-kdiff3-as-a-3-way-merge-tool-with-mercurial-git-and-tower-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Speed up your Grails / Spring Security Development with an Auto Login Bookmarklet</title>
		<link>http://naleid.com/blog/2011/11/29/speed-up-your-grails-spring-security-development-with-autologin-bookmarklet/</link>
		<comments>http://naleid.com/blog/2011/11/29/speed-up-your-grails-spring-security-development-with-autologin-bookmarklet/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 05:35:21 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=479</guid>
		<description><![CDATA[When you&#8217;re doing dev on your website, how often do you log in with the same username and password? I bet it&#8217;s 20+ of times a day when you&#8217;re actively developing. Having to log in manually impedes development speed. If you watch what your browser is doing when it&#8217;s interacting with a Spring Security application, [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re doing dev on your website, how often do you log in with the same username and password?  I bet it&#8217;s 20+ of times a day when you&#8217;re actively developing.</p>
<p>Having to log in manually impedes development speed.  </p>
<p>If you watch what your browser is doing when it&#8217;s interacting with a Spring Security application, you&#8217;ll see that (by default) it&#8217;s POSTing 2 parameters (<code>j_username</code> and <code>j_password</code>) to <code>http://localhost:8080/YOURAPP/j_spring_security_check</code>.</p>
<p>It&#8217;s easy to automate the login process with a little bit of vanilla javascript. Edit this javascript url to replace <code>YOURAPP</code>, <code>YOURUSERNAME</code>, and <code>YOURPASSWORD</code>, then make a bookmark out of it in your browser:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">javascript<span style="color: #339933;">:</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>var<span style="color: #339933;">%</span>20path<span style="color: #339933;">=</span><span style="color: #3366CC;">'http://localhost:8080/YOURAPP/j_spring_security_check'</span><span style="color: #339933;">;</span>var<span style="color: #339933;">%</span>20params<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'j_username'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'YOURUSERNAME'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'j_password'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'YOURPASSWORD'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>var<span style="color: #339933;">%</span>20form<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;form&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;method&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;action&quot;</span><span style="color: #339933;">,</span>path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span>var<span style="color: #339933;">%</span>20key<span style="color: #339933;">%</span>20in<span style="color: #339933;">%</span>20params<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>var<span style="color: #339933;">%</span>20hiddenField<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hidden&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">,</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;value&quot;</span><span style="color: #339933;">,</span>params<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>hiddenField<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Any time you want to log in, just click that bookmark.  You&#8217;re now fully authenticated and in the app without having to interact with the login page. </p>
<p>Alternatively, if you&#8217;re using Google Chrome (or Firefox), you can create a <a href="http://www.google.com/support/chrome/bin/answer.py?answer=95653" onclick="pageTracker._trackPageview('/outgoing/www.google.com/support/chrome/bin/answer.py?answer=95653&amp;referer=');">&#8220;search engine&#8221;</a> associated with a user-defined keyword.  Type the keyword in the address bar to launch it. </p>
<p>You can even parameterize it to log in as a variety of users.</p>
<p>Say that you&#8217;ve got a number of different test users in your app: &#8220;admin&#8221;, &#8220;joeuser&#8221;, &#8220;sales&#8221;, &#8220;finance&#8221;, etc.  All of the test users have the same password, but different usernames with different roles.  If you make the username in the javascript url a &#8220;%s&#8221;, Chrome will replace that &#8220;%s&#8221; with your &#8220;search term&#8221;.</p>
<p>So if your app is &#8220;superapp&#8221; and all passwords are &#8220;password&#8221;, you can use this to create a Chrome search engine that lets you login with whatever test user you want</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">javascript<span style="color: #339933;">:</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>var<span style="color: #339933;">%</span>20path<span style="color: #339933;">=</span><span style="color: #3366CC;">'http://localhost:8080/superapp/j_spring_security_check'</span><span style="color: #339933;">;</span>var<span style="color: #339933;">%</span>20params<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'j_username'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'%s'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'j_password'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'password'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>var<span style="color: #339933;">%</span>20form<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;form&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;method&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;action&quot;</span><span style="color: #339933;">,</span>path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span>var<span style="color: #339933;">%</span>20key<span style="color: #339933;">%</span>20in<span style="color: #339933;">%</span>20params<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>var<span style="color: #339933;">%</span>20hiddenField<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hidden&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">,</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>hiddenField.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;value&quot;</span><span style="color: #339933;">,</span>params<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>hiddenField<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>form.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>To set it up, go into your preferences (cmd-,) and press the &#8220;Manage Search Engines&#8221; button.</p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_manage_search_engines.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_manage_search_engines.png" alt="" title="chrome_manage_search_engines" width="875" height="132" class="aligncenter size-full wp-image-480" /></a></p>
<p>Then under &#8220;Other Search Engines&#8221; click in the box to &#8220;Add a new search engine&#8221;</p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_add_new_search_engine.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_add_new_search_engine.png" alt="" title="chrome_add_new_search_engine"  class="aligncenter wp-image-481" /></a></p>
<p>Name it with your app&#8217;s name (&#8220;superapp login&#8221;), set the keyword to an abbreviation of your app&#8217;s name (&#8220;sa&#8221;), and set the url to the edited javascript command to log in with your app&#8217;s url/username/password (potentially with the username as &#8220;%s&#8221; to parameterize it).</p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_add_new_after.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_add_new_after.png" alt="" title="chrome_add_new_after"  class="aligncenter wp-image-482" /></a></p>
<p>Once you save it, you can then go to your browser&#8217;s address bar (cmd-L) and type your abbreviation (&#8220;sa&#8221;) to get a new &#8220;search engine&#8221;.  Then enter the username you want to log in as.</p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_search_engine_in_action.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/11/chrome_search_engine_in_action.png" alt="" title="chrome_search_engine_in_action" class="aligncenter  wp-image-483" /></a></p>
<p>Hit enter and you&#8217;ll automatically be logged in to your app, without having to interact with your normal login page.</p>
<p>Automating this can help to keep you in the zone, especially if you&#8217;re using a security framework that allows deep linking.  </p>
<p>If deep linking is enabled, the quickest way to get back to the page you&#8217;re iterating on after your session has expired (or you&#8217;ve bounced the app) is to reload the page.  As it&#8217;s redirecting you to the login page, go to your address bar (cmd-L), type your keyword (ex: &#8220;sa&#8221;) and any associated username (ex: &#8220;admin&#8221;) and hit enter.  You&#8217;ll be logged in before the login page displays and Spring Security will redirect you back to the page you originally requested.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2011/11/29/speed-up-your-grails-spring-security-development-with-autologin-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using Dropbox to Share (most of) Your Home Directory Across Multiple Computers</title>
		<link>http://naleid.com/blog/2011/10/03/using-dropbox-to-share-your-home-directory-across-multiple-computers/</link>
		<comments>http://naleid.com/blog/2011/10/03/using-dropbox-to-share-your-home-directory-across-multiple-computers/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 02:44:11 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=433</guid>
		<description><![CDATA[I&#8217;m a very happy customer of Dropbox. It allows painless syncing of files across multiple computers without extra features to complicate it. The top rated answer on Quora to the question &#8220;Why is Dropbox more popular than other programs with similar functionality?&#8221; sums things up perfectly. One of my favorite uses of Dropbox is to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a very happy customer of <a href="http://dropbox.com" onclick="pageTracker._trackPageview('/outgoing/dropbox.com?referer=');">Dropbox</a>.   It allows painless syncing of files across multiple computers without extra features to complicate it.  The <a href="http://www.quora.com/Dropbox/Why-is-Dropbox-more-popular-than-other-programs-with-similar-functionality/answer/Michael-Wolfe" onclick="pageTracker._trackPageview('/outgoing/www.quora.com/Dropbox/Why-is-Dropbox-more-popular-than-other-programs-with-similar-functionality/answer/Michael-Wolfe?referer=');">top rated answer on Quora</a> to the question &#8220;Why is Dropbox more popular than other programs with similar functionality?&#8221; sums things up perfectly.</p>
<p>One of my favorite uses of Dropbox is to sync almost all of the non-machine specific configuration files and directories in my home directory across all my OSX computers (currently my iMac, MacBook Air, and my work laptop).  </p>
<p>Doing this lets me make a configuration change to one computer and have it almost instantly available on any other computer without any manual steps.</p>
<p>This is especially important for my zshell and Vim configurations as I&#8217;m always tweaking those, but it&#8217;s also helpful to have my Documents, Downloads and Pictures shared.</p>
<p>I have a folder in my <code>Dropbox</code> directory called <code>home</code>, I use a script called <code>link.sh</code> to automatically create symlinks in my home directory to the things I&#8217;ve got stored in Dropbox.</p>
<p><code>Dropbox/home</code> currently has these files and directories in it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.ackrc
.dbvis
.groovy
.gvimrc
.hg
.hgignore_global
.ssh
.subversion
.vim
.viminfo
.vimrc
.zshenv
Desktop-starling.local<span style="color: #000000; font-weight: bold;">/</span>   <span style="color: #666666; font-style: italic;"># unique Desktop for my MacBook Air</span>
Desktop-kestrel.local<span style="color: #000000; font-weight: bold;">/</span>    <span style="color: #666666; font-style: italic;"># unique Desktop for my iMac</span>
Desktop-thrush.local<span style="color: #000000; font-weight: bold;">/</span>     <span style="color: #666666; font-style: italic;"># unique Desktop for my work MacBook Pro</span>
Documents<span style="color: #000000; font-weight: bold;">/</span>
Downloads<span style="color: #000000; font-weight: bold;">/</span>
Pictures<span style="color: #000000; font-weight: bold;">/</span>
bin<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>My <code>Dropbox/home</code> directory also has a shell script in it called <code>link.sh</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /usr/bin/env bash</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> linkFile<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">LINK_TO_NAME</span>=<span style="color: #007800;">$2</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$LINK_TO_NAME</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #007800;">LINK_TO_NAME</span>=<span style="color: #007800;">$1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$LINK_TO_NAME</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;**** Found existing <span style="color: #007800;">$LINK_TO_NAME</span>, skipping...&quot;</span>
    <span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-h</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$LINK_TO_NAME</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Already symlinked <span style="color: #007800;">$LINK_TO_NAME</span>, skipping...&quot;</span>
    <span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Linking $1 to <span style="color: #007800;">$LINK_TO_NAME</span>&quot;</span>
        <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #007800;">$PWD</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$1</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$LINK_TO_NAME</span> 
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> F <span style="color: #000000; font-weight: bold;">in</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-a1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> link.sh <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> Desktop <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;^..?$&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;^.*un~$&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> .DS_Store<span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #000000; font-weight: bold;">do</span>
    linkFile <span style="color: #007800;">$F</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">HOSTNAME</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">hostname</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;Desktop-<span style="color: #007800;">$HOSTNAME</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    linkFile <span style="color: #ff0000;">&quot;Desktop-<span style="color: #007800;">$HOSTNAME</span>&quot;</span> <span style="color: #ff0000;">&quot;Desktop&quot;</span>
<span style="color: #000000; font-weight: bold;">else</span> 
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Unable to find Desktop-<span style="color: #007800;">$HOSTNAME</span> to link to Desktop&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>What the script does is:</p>
<ol>
<li><code>cd</code> into the directory that the script is located in (it only symlinks files in the same directory)
<li>list out all of the files and directories in the same directory as the script</li>
<li>filter out the things we don&#8217;t want to link (like <code>.</code>, <code>..</code>, the <code>link.sh</code> script itself, etc)</li>
<li>For all of the files/directories that pass the filter, call <code>linkFile</code> to create a symlink in the current user&#8217;s home directory as long as there isn&#8217;t already a file or a symlink there</li>
<li>Then look for a file called <code>Desktop-$HOSTNAME</code> where <code>$HOSTNAME</code> is the name of the current machine and create a <code>~/Dropbox</code> symlink to it if it&#8217;s found.
</ol>
<p>It should be safe and non-destructive and only create symlinks when there isn&#8217;t anything else there with the same name.</p>
<p>I didn&#8217;t have my <code>Pictures</code>, <code>Documents</code>, and <code>Downloads</code> in my Dropbox for quite a while and was able to get away with the free 2GB plan. I recently upgraded to a paid Dropbox plan as I wanted those directories shared as well (though I exclude a couple of them from my work MacBook Pro).</p>
<p>For &#8220;special&#8221; directories like <code>Desktop</code>, <code>Pictures</code>, <code>Documents</code>, and <code>Downloads</code>, I needed to use <code>sudo rm -r [dirname]</code> to remove it before I could create the symlink (BACKUP THE DIRECTORY FIRST).   </p>
<p>I&#8217;ve been using this for over a year, and haven&#8217;t noticed any apps that care that those directories are symlinks.</p>
<p>Also?  I have used this shell script many times on my systems, and I think it&#8217;s safe, but <strong>PLEASE</strong> backup before using it, or deleting any directories.  An adult crying is not a pretty sight :).</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2011/10/03/using-dropbox-to-share-your-home-directory-across-multiple-computers/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>big &#8211; A Quick Shell/AppleScript/LaunchBar Script to Shout Results</title>
		<link>http://naleid.com/blog/2011/05/17/big-a-quick-shellapplescriptlaunchbar-script-to-shout-results/</link>
		<comments>http://naleid.com/blog/2011/05/17/big-a-quick-shellapplescriptlaunchbar-script-to-shout-results/#comments</comments>
		<pubDate>Wed, 18 May 2011 03:47:17 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=361</guid>
		<description><![CDATA[I threw together a quick shell script, called big that leverages AppleScript and LaunchBar to display results in a huge font. Often, when I&#8217;m demoing something, the results of what I&#8217;m doing don&#8217;t really jump out at my audience. If I really want to get a point across to someone it&#8217;s nice to be able [...]]]></description>
			<content:encoded><![CDATA[<p>I threw together a quick shell script, called <code>big</code> that leverages AppleScript and <a href="http://www.obdev.at/products/launchbar/index.html" onclick="pageTracker._trackPageview('/outgoing/www.obdev.at/products/launchbar/index.html?referer=');">LaunchBar</a> to display results in a huge font.</p>
<p>Often, when I&#8217;m demoing something, the results of what I&#8217;m doing don&#8217;t really jump out at my audience. </p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/05/terminal_result.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/05/terminal_result.png" alt="" title="terminal_result" width="690" height="226" class="aligncenter size-full wp-image-365" /></a></p>
<p>If I really want to get a point across to someone it&#8217;s nice to be able to do it in a really big, clear font.    Just up arrow/ctrl-p to get the last command and append &#8220;<code>| big</code>&#8221; to get this:</p>
<p><a href="http://naleid.com/blog/wp-content/uploads/2011/05/big_result.png"><img src="http://naleid.com/blog/wp-content/uploads/2011/05/big_result.png" alt="" title="big_result" width="1068" height="454" class="alignleft size-full wp-image-366" /></a></p>
<p>This script takes the results of anything you pipe to it and sends it to LaunchBar to display in a really big font.  It get smaller the more text that you send to it, but starts at a ~200pt font.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/bash</span>
&nbsp;
<span style="color: #007800;">TMP_FILE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">mktemp</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>big.XXXXXX<span style="color: #000000; font-weight: bold;">`</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> - <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-20</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$TMP_FILE</span>
&nbsp;
osascript <span style="color: #cc0000; font-style: italic;">&lt;&lt;EOF
tell application &quot;LaunchBar&quot;
    display in large type (do shell script(&quot;cat $TMP_FILE&quot;))
end tell
EOF</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #007800;">$TMP_FILE</span></pre></div></div>

<p>It uses the <code>head</code> command to take only the first 20 lines, in case you&#8217;re trying to display something HUGE (which can kill LaunchBar if you feed it too much).  Adjust the head command appropriately to cap <code>big</code> to more/less output.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2011/05/17/big-a-quick-shellapplescriptlaunchbar-script-to-shout-results/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Movement Shortcuts Wallpaper</title>
		<link>http://naleid.com/blog/2010/10/04/vim-movement-shortcuts-wallpaper/</link>
		<comments>http://naleid.com/blog/2010/10/04/vim-movement-shortcuts-wallpaper/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 01:42:54 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=216</guid>
		<description><![CDATA[I&#8217;ve recently moved back to vim (actually MacVim) after a 5 year hiatus using TextMate. A big part of that move was inspired by Steve Losh&#8217;s recent post Coming Home to Vim which has a number of really great tips. I&#8217;ve cribbed many of them and have my .vimrc / .vim dotfiles checked into a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently moved back to vim (actually MacVim) after a 5 year hiatus using TextMate.  A big part of that move was inspired by Steve Losh&#8217;s recent post <a href="http://stevelosh.com/blog/2010/09/coming-home-to-vim/" onclick="pageTracker._trackPageview('/outgoing/stevelosh.com/blog/2010/09/coming-home-to-vim/?referer=');">Coming Home to Vim</a> which has a number of really great tips.</p>
<p>I&#8217;ve cribbed many of them and have my <a href="http://bitbucket.org/tednaleid/vimrc" onclick="pageTracker._trackPageview('/outgoing/bitbucket.org/tednaleid/vimrc?referer=');">.vimrc / .vim</a> dotfiles checked into a public bitbucket repo.</p>
<p>There have been some big changes in the last 5 years since I&#8217;ve been away from vim (or else I just didn&#8217;t know what the hell I was doing, which is also possible).  The addition of <a href="http://github.com/tpope/vim-pathogen" onclick="pageTracker._trackPageview('/outgoing/github.com/tpope/vim-pathogen?referer=');">pathogen</a> for plugin management makes configuration much easier.  All plugins are completely contained in their own directory.  You can try something out and if it doesn&#8217;t work, just delete the plugin&#8217;s directory to uninstall it.</p>
<p><a href="http://www.vim.org/scripts/script.php?script_id=1658" onclick="pageTracker._trackPageview('/outgoing/www.vim.org/scripts/script.php?script_id=1658&amp;referer=');">NerdTree</a> is nice, but <a href="http://peepcode.com/products/peepopen" onclick="pageTracker._trackPageview('/outgoing/peepcode.com/products/peepopen?referer=');">PeepOpen</a>&#8216;s integration with MacVim for finding/opening files beats TextMate&#8217;s cmd-T hands down.</p>
<p>I tend to be a hands-on, visual learner, so I looked around for a nice wallpaper to help me learn and retain the panoply of vim movement commands, but all I was able to find were simple lists of commands, so I decided to whip my own version up.</p>
<p>It shows all of the default movement commands, each command is placed relative to the center of the image and are ordered based on how far your cursor will likely travel.   All of these are active in vim&#8217;s &#8220;normal&#8221; mode (though I believe most if not all of them will also work in &#8220;visual&#8221; mode.</p>
<p>I also find it useful to set my MacVim window to be slightly transparent so that I can see the shortcuts through the window if I need to.  In MacVim 7.3 you need to turn on the Advanced->&#8221;Use experimental renderer&#8221; option.  Then you can &#8220;:set transp=20&#8243; to make it 20% transparent (which feels right to me, but you might want to move it up/down depending on your preferences).</p>
<p>You can <a href="http://bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts.png" onclick="pageTracker._trackPageview('/outgoing/bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts.png?referer=');">download the full size (1900&#215;1200)</a> (or <a href="http://bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts2560x1600.png" onclick="pageTracker._trackPageview('/outgoing/bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts2560x1600.png?referer=');">2560&#215;1600</a>) image for yourself.</p>
<p><a href="http://bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts.png" onclick="pageTracker._trackPageview('/outgoing/bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts.png?referer=');"><img src="http://bitbucket.org/tednaleid/vim-shortcut-wallpaper/raw/tip/vim-shortcuts.png" alt="Vim Shortcuts Wallpaper" height="600"/></a></p>
<p>I&#8217;ve also got the original OmniGraffle file that I used to create it <a href="http://bitbucket.org/tednaleid/vim-shortcut-wallpaper/src" onclick="pageTracker._trackPageview('/outgoing/bitbucket.org/tednaleid/vim-shortcut-wallpaper/src?referer=');">checked in to a BitBucket repo</a> if anyone feels like remixing it or adding their own shortcuts or customizations to it.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2010/10/04/vim-movement-shortcuts-wallpaper/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>Running Grails Unit and Integration Tests in Parallel</title>
		<link>http://naleid.com/blog/2010/08/26/running-grails-unit-and-integration-tests-in-parallel/</link>
		<comments>http://naleid.com/blog/2010/08/26/running-grails-unit-and-integration-tests-in-parallel/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 03:31:31 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=205</guid>
		<description><![CDATA[The number of tests on my current project is getting close to the 2000 mark (1504 unit and 351 integration) and running the full suite can take 4+ minutes to execute. When you&#8217;re trying to do TDD and want to run all tests before pushing your code out to the shared repository, this length of [...]]]></description>
			<content:encoded><![CDATA[<p>The number of tests on my current project is getting close to the 2000 mark (1504 unit and 351 integration) and running the full suite can take 4+ minutes to execute.</p>
<p>When you&#8217;re trying to do TDD and want to run all tests before pushing your code out to the shared repository, this length of time can really bog you down when it happens a number of times per day.</p>
<p>There are a number of tests that we need to go back in and refactor to be faster, but I wanted to see how much of a boost I could get by running unit and integration tests in parallel.  </p>
<p>With 2 threads (one for unit, one for integration) the best case would be taking 50% of the time that it takes to run serially.  That would only happen if my unit and integration tests took the same amount of time to run.  For my tests, I was able to get a 39% speed improvement (with the integration tests taking a bit longer than the unit tests).</p>
<p>Here&#8217;s the script:<br />
<span id="more-205"></span><br />
(just save it as splitTests.groovy in your path and make it executable, then run it in your grails project dir)</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/env groovy</span>
&nbsp;
<span style="color: #aaaadd; font-weight: bold;">Map</span> exitStatuses <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>:<span style="color: #66cc66;">&#93;</span>.<span style="color: #663399;">asSynchronized</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> currentDir<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #ff0000;">'pwd'</span>.<span style="color: #993399; font-weight: bold;">execute</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span>.<span style="color: #006600;">trim</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> getGrailsPropertyArgs<span style="color: #66cc66;">&#40;</span>group<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">def</span> testDir <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;${currentDir()}/test-$group&quot;</span>
	<span style="color: #66cc66;">&#91;</span>
	    <span style="color: #ff0000;">&quot;-Dgrails.work.dir=${testDir}&quot;</span>,
	    <span style="color: #ff0000;">&quot;-Dgrails.project.class.dir=${testDir}/classes&quot;</span>,
	    <span style="color: #ff0000;">&quot;-Dgrails.project.test.class.dir=${testDir}/test-classes&quot;</span>,
	    <span style="color: #ff0000;">&quot;-Dgrails.project.test.reports.dir=${testDir}/test-reports&quot;</span>
	<span style="color: #66cc66;">&#93;</span>.<span style="color: #663399;">join</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">synchronized</span> out<span style="color: #66cc66;">&#40;</span>group, message<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #993399;">println</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;${group.padLeft(12, ' ')}: $message&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#91;</span>
        integration: <span style="color: #ff0000;">'integration:'</span>,
        unit: <span style="color: #ff0000;">'unit:'</span>
<span style="color: #66cc66;">&#93;</span>.<span style="color: #663399;">collect</span> <span style="color: #66cc66;">&#123;</span> testGroup, args <span style="color: #66cc66;">-&gt;</span>
	<span style="color: #aaaadd; font-weight: bold;">Thread</span>.<span style="color: #993399;">start</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">def</span> command <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;grails ${getGrailsPropertyArgs(testGroup)} test-app $args&quot;</span>
		out testGroup, command
		exitStatuses<span style="color: #66cc66;">&#91;</span>testGroup<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> command.<span style="color: #993399; font-weight: bold;">execute</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">with</span> <span style="color: #66cc66;">&#123;</span> proc <span style="color: #66cc66;">-&gt;</span>
			proc.<span style="color: #b1b100;">in</span>.<span style="color: #FFCC33;">eachLine</span> <span style="color: #66cc66;">&#123;</span> line <span style="color: #66cc66;">-&gt;</span> out testGroup, line <span style="color: #66cc66;">&#125;</span>
			proc.<span style="color: #006600;">waitFor</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
			proc.<span style="color: #006600;">exitValue</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
		<span style="color: #66cc66;">&#125;</span>
		out testGroup, <span style="color: #ff0000;">&quot;exit value: ${exitStatuses[testGroup]}&quot;</span>
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span> it.<span style="color: #663399;">join</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> failingGroups <span style="color: #66cc66;">=</span> exitStatuses.<span style="color: #663399;">findAll</span> <span style="color: #66cc66;">&#123;</span> it.<span style="color: #006600;">value</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>failingGroups<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;All tests were successful!&quot;</span>
<span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span>
	failingGroups.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span> failingGroup, exitStatus <span style="color: #66cc66;">-&gt;</span>
		out<span style="color: #66cc66;">&#40;</span>failingGroup, <span style="color: #ff0000;">&quot;WARNING: '$failingGroup' exit status was $exitStatus&quot;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#125;</span>
	<span style="color: #aaaadd; font-weight: bold;">System</span>.<span style="color: #006600;">exit</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The script is pretty simple.  It creates one thread for unit tests, and one for integration tests.  It then creates a grails test-app command that includes a number of grails system properties necessary to define unique target and working directories so the threads don&#8217;t step all over each other.</p>
<p>As the threads run, they spit their output to the command line with a prefix on each line showing which thread it came from, ex:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">...
 <span style="color: #006600;">integration</span>: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">ProductTests</span>...<span style="color: #006600;">PASSED</span>
        unit: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">QuestionUnitTests</span>...<span style="color: #006600;">PASSED</span>
 integration: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">TransactionalFalseTests</span>...<span style="color: #006600;">PASSED</span>
        unit: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">RateAreaUnitTests</span>...<span style="color: #006600;">PASSED</span>
        unit: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">RateDependentTypeUnitTests</span>...<span style="color: #006600;">PASSED</span>
 integration: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">filter</span>.<span style="color: #006600;">EmployerFiltersTests</span>...<span style="color: #006600;">PASSED</span>
        unit: Running test com.<span style="color: #006600;">bloomhealthco</span>.<span style="color: #006600;">domain</span>.<span style="color: #006600;">RateUnitTests</span>...<span style="color: #006600;">PASSED</span>
...</pre></div></div>

<p>When it&#8217;s done, it checks the exit status code of each individual run.  If any failed, the splitTests script will enumerate the ones that failed and will also return a non-zero exit status code.</p>
<p>The first time you run this, it will probably be slow, as each thread is compiling it&#8217;s own set of class files into it&#8217;s own &#8220;target&#8221; directory.  After the initial compilation, things should be a lot quicker for the 2nd run.</p>
<p>If you&#8217;ve only got a couple of tests, you likely won&#8217;t see any speedup from this as the fixed grails cost for boostrapping the environment in each thread will outweigh the parallelization of tests.</p>
<p>If you&#8217;ve got other types of tests that you&#8217;re running, it&#8217;s easy to just add other phases into the existing threads (or create new threads for them), just by adding to the map that we spin through.</p>
<p>I&#8217;ll probably dig into the grails internals some more to see if some of it can be refactored to make running tests in parallel easier.  The latest versions of JUnit have some support for running tests in parallel, but it isn&#8217;t easily achieved with the current grails test/environment bootstrap.   </p>
<p>My long term goal is to create a grails script that lets the user specify a number of worker threads to be used for testing.  Those workers are then fed test classes to chew on and the load would be distributed better than it is currently.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2010/08/26/running-grails-unit-and-integration-tests-in-parallel/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Groovy Each Iterator with Peek-ahead at Next Collection Value</title>
		<link>http://naleid.com/blog/2010/06/15/groovy-each-iterator-with-peek-ahead-at-next-collection-value/</link>
		<comments>http://naleid.com/blog/2010/06/15/groovy-each-iterator-with-peek-ahead-at-next-collection-value/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 04:55:10 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=191</guid>
		<description><![CDATA[Groovy closures combined with iterators make it simple to create our own enhanced iterators that let us process a collection how we want to. I write my own custom iterators all the time and name them something descriptive. This makes the code much more readable. Rather than trying to decipher what a for loop is [...]]]></description>
			<content:encoded><![CDATA[<p>Groovy closures combined with iterators make it simple to create our own enhanced iterators that let us process a collection how we want to.</p>
<p>I write my own custom iterators all the time and name them something descriptive.  This makes the code much more readable. Rather than trying to decipher what a for loop is trying to do, we wrap up all of that iteration logic into a meaningful name and we cleanly separate that iteration from the processing that we&#8217;re doing with each element.</p>
<p>This kind of design is a core concept in Uncle Bob&#8217;s <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882?referer=');">Clean Code</a>, one of my favorite programming books in the last few years.</p>
<p>This example iterates over a collection and calls the passed in closure until we hit a value greater than 5.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> eachUntilGreaterThanFive <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> collection, closure <span style="color: #66cc66;">-&gt;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span> value <span style="color: #b1b100;">in</span> collection <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span> value  <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">5</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #000000; font-weight: bold;">break</span>
        closure<span style="color: #66cc66;">&#40;</span>value<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> a <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">6</span>, <span style="color: #cc66cc;">7</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
eachUntilGreaterThanFive<span style="color: #66cc66;">&#40;</span>a<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #993399;">println</span> it
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>prints:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #cc66cc;">1</span>
<span style="color: #cc66cc;">2</span>
<span style="color: #cc66cc;">3</span>
<span style="color: #cc66cc;">4</span>
<span style="color: #cc66cc;">5</span></pre></div></div>

<p>This code makes it obvious what the iterator is doing (looping till we hit a condition) as well as what will happen with each element iterated over (print it out).</p>
<p>For a real life example, I had a need to iterate over a list of values and where I needed both the current object as well as a peek at the next object in the list.</p>
<p>Doing this is Java is a bit of a pain, but groovy makes it easy to write and (hopefully) to read, we can also add it directly onto the Collection metaClass so that it&#8217;s available for all of our Collection instances:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #aaaadd; font-weight: bold;">Collection</span>.<span style="color: #006600;">metaClass</span>.<span style="color: #006600;">eachWithPeek</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> closure <span style="color: #66cc66;">-&gt;</span>
    <span style="color: #000000; font-weight: bold;">def</span> last <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">null</span>
    delegate<span style="color: #66cc66;">?</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span> current <span style="color: #66cc66;">-&gt;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>last<span style="color: #66cc66;">&#41;</span> closure<span style="color: #66cc66;">&#40;</span>last, current<span style="color: #66cc66;">&#41;</span>
        last <span style="color: #66cc66;">=</span> current
    <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>last<span style="color: #66cc66;">&#41;</span> closure<span style="color: #66cc66;">&#40;</span>last, <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>These test cases show that as we iterate through the collection, we can see the current item and peek at the next one (if any).  If the collection is empty, we don&#8217;t execute the closure it, and if we&#8217;re at the end of the list there isn&#8217;t anything to peek at:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">eachWithPeek</span> <span style="color: #66cc66;">&#123;</span> current, peek <span style="color: #66cc66;">-&gt;</span>
    <span style="color: #000000; font-weight: bold;">assert</span> <span style="color: #000000; font-weight: bold;">false</span> <span style="color: #808080; font-style: italic;">// shouldn't get here, nothing to iterate through</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">eachWithPeek</span> <span style="color: #66cc66;">&#123;</span> current, peek <span style="color: #66cc66;">-&gt;</span>
    <span style="color: #000000; font-weight: bold;">assert</span> current <span style="color: #66cc66;">==</span> <span style="color: #cc66cc;">1</span>
    <span style="color: #000000; font-weight: bold;">assert</span> peek <span style="color: #66cc66;">==</span> <span style="color: #000000; font-weight: bold;">null</span>  <span style="color: #808080; font-style: italic;">// only 1 element, nothing to peek at</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> results <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>
<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">eachWithPeek</span> <span style="color: #66cc66;">&#123;</span> current, peek <span style="color: #66cc66;">-&gt;</span>
    results <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #66cc66;">&#91;</span>current, peek<span style="color: #66cc66;">&#93;</span>
<span style="color: #66cc66;">&#125;</span>
<span style="color: #000000; font-weight: bold;">assert</span> results <span style="color: #66cc66;">==</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">5</span>, <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2010/06/15/groovy-each-iterator-with-peek-ahead-at-next-collection-value/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using a Unique Grails Working Directory for each Mercurial Branch</title>
		<link>http://naleid.com/blog/2010/05/07/using-a-unique-grails-working-directory-for-each-mercurial-branch/</link>
		<comments>http://naleid.com/blog/2010/05/07/using-a-unique-grails-working-directory-for-each-mercurial-branch/#comments</comments>
		<pubDate>Fri, 07 May 2010 18:07:40 +0000</pubDate>
		<dc:creator>tednaleid</dc:creator>
				<category><![CDATA[command line]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://naleid.com/blog/?p=184</guid>
		<description><![CDATA[At work, we&#8217;re using mercurial for our source control. As we&#8217;ve released code to production we&#8217;ve needed to branch our repository to support what&#8217;s in production as well as ongoing development. By default, grails uses ~/.grails as the working directory. If you&#8217;re doing branchy development, you can run into problems with this if you&#8217;ve got [...]]]></description>
			<content:encoded><![CDATA[<p>At work, we&#8217;re using <a href="http://mercurial.selenic.com/" onclick="pageTracker._trackPageview('/outgoing/mercurial.selenic.com/?referer=');">mercurial</a> for our source control.  As we&#8217;ve released code to production we&#8217;ve needed to branch our repository to support what&#8217;s in production as well as ongoing development.  </p>
<p>By default, grails uses <code>~/.grails</code> as the working directory.  If you&#8217;re doing branchy development, you can run into problems with this if you&#8217;ve got plugins installed in one branch that aren&#8217;t in the other.  Having a unique directory per branch prevents you from having to run <code>grails clean</code> all the time.</p>
<p>Here&#8217;s a quick shell script that changes the grails working directory to have the branch name as a suffix if your source is contained in a mercurial repository (ex: the default branch would be <code>~/.grails_default</code> and the 1.0 branch would be <code>~/.grails_1.0</code>).  If your application is not in a repo, it just uses the regular <code>~/.grails directory</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #007800;">HG_BRANCH</span>=<span style="color: #000000; font-weight: bold;">`</span>hg branch <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">GRAILS_SCRIPT</span>=<span style="color: #007800;">$GRAILS_HOME</span><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>grails
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$HG_BRANCH</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">GRAILS_WORK_DIR</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> ~<span style="color: #000000; font-weight: bold;">`/</span>.grails_<span style="color: #007800;">$HG_BRANCH</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** grails working directory: <span style="color: #007800;">$GRAILS_WORK_DIR</span>&quot;</span>
	<span style="color: #007800;">$GRAILS_SCRIPT</span> -Dgrails.work.dir=<span style="color: #007800;">$GRAILS_WORK_DIR</span> $<span style="color: #000000; font-weight: bold;">@</span>
<span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** default grails working directory&quot;</span>
	<span style="color: #007800;">$GRAILS_SCRIPT</span> $<span style="color: #000000; font-weight: bold;">@</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Just save this script as &#8220;grails&#8221; and put it in your PATH before the $GRAILS_HOME/bin directory (also make sure that you&#8217;ve defined $GRAILS_HOME).  I have a ~/bin directory that&#8217;s the first thing in my PATH.</p>
<p>If you use the grails-debug command, you can repeat these steps for that, just change <code>GRAILS_SCRIPT</code> to <code>$GRAILS_HOME/bin/grails-debug</code>.</p>
<p>This same technique could easily be modified to be used for other source control systems such as git or subversion.</p>
]]></content:encoded>
			<wfw:commentRss>http://naleid.com/blog/2010/05/07/using-a-unique-grails-working-directory-for-each-mercurial-branch/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

