<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Made by Nathan]]></title>
  <link href="http://madebynathan.com/atom.xml" rel="self"/>
  <link href="http://madebynathan.com/"/>
  <updated>2017-02-18T08:10:36+07:00</updated>
  <id>http://madebynathan.com/</id>
  <author>
    <name><![CDATA[Nathan Broadbent]]></name>
    <email><![CDATA[nathan.f77@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Raspberry Pi Microwave]]></title>
    <link href="http://madebynathan.com/2013/07/10/raspberry-pi-powered-microwave/"/>
    <updated>2013-07-10T18:51:47+07:00</updated>
    <id>http://madebynathan.com/2013/07/10/raspberry-pi-powered-microwave</id>
    <content type="html"><![CDATA[<p>A few months ago, I was inspired by <a href="http://www.reddit.com/r/CrazyIdeas/comments/1djrnx/food_items_should_have_qr_codes_that_instruct_the/">this post</a> on Reddit, titled: <strong>Food items should have QR codes that instruct the microwave exactly what to do. Like high for 2 minutes, let stand 1 minute, medium 1 minutes.</strong>.</p>

<p>I thought this was a pretty cool idea, and that it would be a fun project for a Raspberry Pi. I agreed with the people who thought using UPC barcodes would be better, since products already have them, so I went with a barcode scanner + online product database.</p>

<p>Here&rsquo;s a summary of the features that I&rsquo;ve added to my microwave:</p>

<ul>
<li>Re-designed touchpad</li>
<li>Nicer sounds</li>
<li>Clock is automatically updated from the internet</li>
<li>Can be controlled with voice commands</li>
<li>Can use a barcode scanner to look up cooking instructions from an online database</li>
<li>There weren&rsquo;t any online microwave cooking databases around, so I made one: <a href="http://microwavecookingdb.com">http://microwavecookingdb.com</a></li>
<li>The microwave has a web page so you can control it from your phone (why not), and set up cooking instructions for products</li>
<li>Tweets after it&rsquo;s finished cooking something (See <a href="https://twitter.com/rbmicrowave">https://twitter.com/rbmicrowave</a>)</li>
</ul>


<h2>Demo Video</h2>

<iframe width="100%" height="400" src="http://madebynathan.com//www.youtube.com/embed/e2YtARzJTys" frameborder="0" allowfullscreen></iframe>


<h2>Using a Raspberry Pi to cook a Raspberry Pie</h2>

<p><a href="http://frugalfastfun.blogspot.co.nz/2009/08/surprise-pies-using-microwave.html">Here&rsquo;s the recipe</a>.</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/ingredients-resized-thumb.jpg" alt="Raspberry Pie Ingredients" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/mixing-resized-thumb.jpg" alt="Raspberry Pie Mixing" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/cooking_pie_filling-resized-thumb.jpg" alt="Raspberry Pie Cooking" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/raspberry_pi_raspberry_pie-resized-thumb.jpg" alt="Raspberry Pi - Raspberry Pie" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/a_slice_of_pi-resized-thumb.jpg" alt="A slice of Pi" /></p>

<hr/>


<h3>Keep reading below if you&rsquo;re interested in electronics or software:</h3>

<h2>Hardware</h2>

<p>I used a microwave with a touchpad, and discovered that the touchpad was a button matrix. I took photos of the touchpad and traced the wires, so that I could tell which pins corresponded to which buttons.</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/touchpad_no_traces-resized-thumb.jpg" alt="Touchpad" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/touchpad_traces-resized-thumb.jpg" alt="Touchpad Traces" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/original_touchpad-resized-thumb.jpg" alt="Original Touchpad UI" /></p>

<p>I initially wanted to put everything in a case outside the microwave, but I decided that it would be more challenging and fun to try and fit everything inside. Here&rsquo;s all the PCB revisions, before I settled on a design that would fit neatly on top of the microwave&rsquo;s original PCB.</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/pcb_1-resized-thumb.jpg" alt="PCB revision 1" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/pcb_2-resized-thumb.jpg" alt="PCB revision 2" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/pcb_3-resized-thumb.jpg" alt="PCB revision 3" /></p>

<p>I used shift registers and optocouplers to control the touchpad pins. To listen for touchpad presses, an output shift register scans one line at a time on the first touchpad layer, and an input shift register listens for connections to the second layer.</p>

<p>I unsoldered the touchpad connector from the original circuit board, and replaced it with a row of pin headers. I then used the original touchpad connector on my PCB, so that my circuit acts as a kind of proxy for button presses.</p>

<p>Here&rsquo;s the final product after transferring toner, etching, drilling, and soldering. (I had to use the ribbon cables to save space.)</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/ready_to_etch-resized-thumb.jpg" alt="Ready to Etch" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/soldered-resized-thumb.jpg" alt="Everything Soldered" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/pcb_bottom-resized-thumb.jpg" alt="PCB Bottom" /></p>

<p>And here&rsquo;s how it fits on top of the microwave controller:</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/plugged_in1-resized-thumb.jpg" alt="Plugged In" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/plugged_in2-resized-thumb.jpg" alt="Plugged In" /></p>

<p>When I peeled off the old touchpad overlay, it became wrinkled and ugly, so I thought I may as well have a go at redesigning the interface. My goal was to get rid of the features I don&rsquo;t really use, and make the basic functions more convenient. The top two rows of buttons are now dedicated to &ldquo;one touch&rdquo; cooking times, for either &ldquo;high&rdquo; or &ldquo;medium&rdquo; power. You can also set the time and power manually.</p>

<p><img class="lightbox" width="145" src="http://madebynathan.com/images/posts/2013/07/touchpad-resized-thumb.jpg" alt="Touchpad" /></p>

<p>You might have noticed that I started the project with the intention of using an <a href="http://arduino.cc/en/Main/ArduinoBoardNano">Arduino Nano</a> plugged into a Raspberry Pi USB port. This was because I was a) familiar with the Arduino, b) not familiar with the Raspberry Pi GPIO, and c) thought it would make testing and debugging a bit easier, since I could just plug the Arduino into my laptop.</p>

<p>However, it turns out that my Raspberry Pi had some issues with the arduino&rsquo;s FTDI chip if the Raspberry Pi was turned on while the Arduino was plugged in. It wouldn&rsquo;t recognize the Arduino until I unplugged it, and then plugged it back in again.</p>

<p>So I decided to make an Arduino Nano =&gt; Raspberry Pi GPIO adapter, and port my Arduino code to the Raspberry Pi GPIO using the <a href="http://wiringpi.com/">WiringPi</a> library.</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/arduino_raspberry_adapter-resized-thumb.jpg" alt="Arduino to Raspberry Pi adapter" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/raspberry_adapter_top-resized-thumb.jpg" alt="Arduino to Raspberry Pi adapter" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/raspberry_adapter_bottom-resized-thumb.jpg" alt="Arduino to Raspberry Pi adapter" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/raspberry_adapter_connected-resized-thumb.jpg" alt="Arduino to Raspberry Pi adapter" /></p>

<p>The Raspberry Pi is powered by a USB hub, which is also plugged into the Raspberry Pi&rsquo;s USB port. To power the hub, I wired up a power adapter to the microwave&rsquo;s power source. There&rsquo;s also a USB powered speaker, USB microphone, wifi adapter, and barcode scanner.</p>

<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/power_adapter-resized-thumb.jpg" alt="Power adapter" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/usb_hub-resized-thumb.jpg" alt="USB Hub" />
<img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/07/microphone_wifi-resized-thumb.jpg" alt="Microphone + Wifi" /></p>

<h2>Microwave Software</h2>

<p>All the software running on the Raspberry Pi is hosted at: <a href="https://github.com/ndbroadbent/raspberry_picrowave">https://github.com/ndbroadbent/raspberry_picrowave</a>.</p>

<p>There are 4 main components:</p>

<h3>Microwave Daemon</h3>

<p>This runs the code that listens for touchpad button presses, and controls the microwave. It also accepts TCP connections so that other programs can send commands or request information about the microwave&rsquo;s status.</p>

<h3>Barcode Instructions</h3>

<p>This program listens to the barcode scanner, and requests product information from the Microwave Cooking Database. It also runs the cooking programs.</p>

<h3>Voice Control</h3>

<p>I used <a href="http://cmusphinx.sourceforge.net/">PocketSphinx</a> for voice recognition, which worked very well with my small <a href="https://github.com/ndbroadbent/raspberry_picrowave/blob/master/voice_control/corpus.txt">corpus</a>. I embedded Ruby in the <a href="https://github.com/ndbroadbent/raspberry_picrowave/blob/master/voice_control/pocketsphinx_microwave.c">pocketsphinx_contiunous</a> C program, so that it would be easier to <a href="https://github.com/ndbroadbent/raspberry_picrowave/blob/master/voice_control/voice_control.rb">script voice commands</a> and send commands to the microwave daemon. It turns out that the acoustics of my kitchen seem to mess up the recognition, so it won&rsquo;t be used very often.</p>

<h3>Sinatra App</h3>

<p>There&rsquo;s a simple <a href="https://github.com/ndbroadbent/raspberry_picrowave/blob/master/sinatra_app/microwave_webapp.rb">sinatra web application</a> that lets you control the microwave from your phone or computer. This may not be a big selling point. It uses a <a href="https://github.com/ndbroadbent/raspberry_picrowave/blob/master/sinatra_app/public/application.js">JavaScript EventSource</a> to push updates to the browser, so you could have hundreds of users connected to your microwave at once.</p>

<p>If any barcodes are scanned that can&rsquo;t be found on the Microwave Cooking Database, this webpage will display the unknown barcodes and provide a link to add the new product.</p>

<h2>Microwave Cooking Database</h2>

<p>I couldn&rsquo;t find any existing websites with a database of microwave cooking instructions, so <a href="http://www.microwavecookingdb.com/">I made one</a>.</p>

<p><a href="http://www.microwavecookingdb.com" target="_blank">
  <img src="http://madebynathan.com/images/posts/2013/07/mwcdb-resized-post.png" alt="Microwave Cooking Database" />
</a></p>

<p>If cooking instructions are posted for a 1000W microwave, you can request the instructions for a 700W microwave, and the cooking times will be automatically adjusted.</p>

<p>So if you&rsquo;re also planning on making an internet connected microwave with a barcode scanner, please feel free to sign up and add some products.</p>

<h2>Patents?</h2>

<p>Nope, this is just a fun project. <a href="http://www.amazon.com/Beyond-WBYMW1-850-Watt-Microwave-Scanning/dp/B0000C8W7Z/ref=cm_cr_pr_product_top">Microwaves with barcode scanners already exist</a>, and <a href="http://www.google.com/patents/US4323773">most</a> of these <a href="http://www.google.com/patents/US6124583">features</a> are <a href="http://www.google.com/patents/US6444965">already</a> <a href="http://www.google.com/patents/EP1117275A2?cl=en">patented</a>.</p>

<h2>Thanks for reading!</h2>

<p>I&rsquo;d be interested to hear if you do something similar, or make use of <a href="http://www.microwavecookingdb.com">http://www.microwavecookingdb.com</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ubuntu Keyboard Shortcut: Open a selected file in Sublime Text 2]]></title>
    <link href="http://madebynathan.com/2013/03/29/keyboard-shortcut-to-open-selected-file-in-sublime-text-2/"/>
    <updated>2013-03-29T17:44:58+07:00</updated>
    <id>http://madebynathan.com/2013/03/29/keyboard-shortcut-to-open-selected-file-in-sublime-text-2</id>
    <content type="html"><![CDATA[<p>Whenever I&rsquo;m looking at backtraces, logs, or failing tests in the terminal, I often need to open one of those files in my text editor. It was previously a semi-arduous process that involved highlighting, copying, pasting and the return key. Now, all I need to do is double-click or highlight a line, and then press a keyboard shortcut to open that file &amp; line in my text editor (currently <a href="http://www.sublimetext.com/2">Sublime Text 2</a>.) I&rsquo;ve also added a thing to my <code>$PROMPT_SCRIPT</code> that stores my terminal&rsquo;s most recent directory in <code>~/.cwd~</code>, so that the script can handle relative paths. (Most of the time I&rsquo;m just in the root folder of a given project.)</p>

<p>One extra feature for Ruby developers is support for backtrace lines like this:</p>

<div class="highlight"><pre><code class="ruby"><span class="n">app</span><span class="o">/</span><span class="n">models</span><span class="o">/</span><span class="n">post</span><span class="o">.</span><span class="n">rb</span><span class="p">:</span><span class="mi">225</span><span class="ss">:in</span> <span class="sb">`sharing_is_caring&#39;</span>
</code></pre></div>


<p>If you double-click that file, you&rsquo;ll end up with the following selection: <strong>app/models/post.rb:225:in</strong>. The script will automatically strip the trailing <strong>:in</strong>, so you can just double-click instead of manually highlighting.</p>

<h3>Requirements</h3>

<ul>
<li>Ubuntu</li>
<li>xclip (install with <code>sudo apt-get install xclip</code>)</li>
<li>A text editor, such as <a href="http://www.sublimetext.com/2">Sublime Text 2</a>.</li>
</ul>


<h3>Installation</h3>

<ul>
<li>Download the <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bin/open_selected_in_editor">open_selected_in_editor</a> script to somewhere like <code>~/bin</code>.</li>
</ul>


<div class="highlight"><pre><code class="bash">mkdir -p ~/bin
wget https://raw.github.com/ndbroadbent/dotfiles/master/bin/open_selected_in_editor -O ~/bin/open_selected_in_editor
chmod +x ~/bin/open_selected_in_editor
</code></pre></div>


<ul>
<li>Modify the script to use your preferred text editor</li>
</ul>


<h3>Set up current working directory support</h3>

<p>Add the following line to your <code>~/.bashrc</code>:</p>

<div class="highlight"><pre><code class="bash">PROMPT_COMMAND+<span class="o">=</span><span class="s2">&quot;pwd &gt; ~/.cwd~;&quot;</span>
</code></pre></div>


<p>This means that every time you press return in the terminal, the script can use your current directory to determine an absolute path for a highlighted file. It&rsquo;s not completely foolproof, but good enough for me.</p>

<h3>Set up a keyboard shortcut in Ubuntu 12.04</h3>

<ul>
<li>Go to <strong>System Settings</strong> &ndash;> <strong>Keyboard</strong> &ndash;> <strong>Shortcuts</strong> &ndash;> <strong>Custom Shortcuts</strong></li>
<li>Click the <strong>+</strong> to add a new shortcut with:

<ul>
<li>Name: <strong>Open selected in editor</strong></li>
<li>Command: <strong>~/bin/open_selected_in_editor</strong></li>
</ul>
</li>
<li>Set the keyboard shortcut. I like <em>Ctrl+Shift+X</em>.</li>
</ul>


<p><img class="lightbox thumb" src="http://madebynathan.com/images/posts/2013/03/keyboard_shortcuts.jpg" alt="Ubuntu Keyboard Shortcuts" /></p>

<p>All done! Now you can highlight a filename in the terminal, press your keyboard shortcut, and open it in your editor without the need to copy &amp; paste filenames. Please let me know if you need any help, but I&rsquo;m sorry I don&rsquo;t know how to do this in OS X or Windows.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Open files generated by 'rails generate' in your editor]]></title>
    <link href="http://madebynathan.com/2012/12/20/open-files-generated-by-rails-generate-in-your-editor/"/>
    <updated>2012-12-20T07:02:20+07:00</updated>
    <id>http://madebynathan.com/2012/12/20/open-files-generated-by-rails-generate-in-your-editor</id>
    <content type="html"><![CDATA[<p><small>
Note: This post is for people who use the terminal to run Rails generators. It probably won&rsquo;t interest you if your editor has a plugin to run them.
</small></p>

<p>After running a Rails generator, you&rsquo;ll often need to edit the generated files in your text editor.</p>

<p>Rails 4 may soon have the ability to open generated files in your text editor if you pass the <code>--editor</code> option on the command line.
You can <a href="https://github.com/rails/rails/pull/8553">follow my pull request for more details</a>.</p>

<p>If you use the <code>--editor</code> option (or its <code>-e</code> alias), the generator will open all generated or copied files in your text editor.
The default editor is your <code>GUI_EDITOR</code> or <code>EDITOR</code> environment variable, but you can set the editor manually with <code>--editor=manual-code-editor</code>.</p>

<p>Rails 3 isn&rsquo;t accepting any new features, so here&rsquo;s how you can use the <code>--editor</code> option for your Rails 3 apps:</p>

<h2>Single Rails 3 app</h2>

<p>To install the <code>--editor</code> option in a single Rails 3 app, run the following command from your app directory:</p>

<div class="highlight"><pre><code class="bash">curl https://gist.github.com/raw/4342095/rails -o script/rails
</code></pre></div>


<p>This will update <code>script/rails</code>, and you can commit the change.</p>

<h2>Globally for all Rails 3 apps</h2>

<p>If you are developing a lot of different apps, it might be too much hassle to update all of them. Instead, you can download the custom <code>rails</code> script to your <code>/bin</code> directory, and add some shortcut functions to your <code>.bashrc</code>.</p>

<h3>Download script:</h3>

<div class="highlight"><pre><code class="bash">sudo curl https://gist.github.com/raw/4342095/rails3_with_editor -o /bin/rails3_with_editor
sudo chmod +x /bin/rails3_with_editor
</code></pre></div>


<h3>Add shortcut functions:</h3>

<p>Add the following to your <code>~/.bashrc</code>:</p>

<div class="highlight"><pre><code class="bash">rge<span class="o">()</span> <span class="o">{</span> rails3_with_editor generate <span class="s2">&quot;$@&quot;</span> --editor; <span class="o">}</span>
rgm<span class="o">()</span> <span class="o">{</span> rails3_with_editor generate migration <span class="s2">&quot;$@&quot;</span> --editor; <span class="o">}</span>
</code></pre></div>


<p>Now you can run <code>rgm</code> to generate a migration from any Rails 3 app.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Automatically run 'bundle install' when Bundler can't find a gem]]></title>
    <link href="http://madebynathan.com/2012/12/18/automatically-run-bundle-install-if-bundler-raises-gemnotfound/"/>
    <updated>2012-12-18T13:56:01+07:00</updated>
    <id>http://madebynathan.com/2012/12/18/automatically-run-bundle-install-if-bundler-raises-gemnotfound</id>
    <content type="html"><![CDATA[<p>Every Rails developer has probably experienced the following error:</p>

<div class="highlight"><pre><code class="bash"><span class="sb">Could not find &lt;gem&gt; in any of the sources</span>
<span style="color: #FD0;">Run `bundle install` to install missing gems.</span>
</code></pre>
</div>


<p>This happens if you or someone else adds a gem to your <code>Gemfile</code>, or if a gem version is updated in <code>Gemfile.lock</code>,
and you forget to run <code>bundle install</code> before running a Rails command.</p>

<p>Here&rsquo;s a simple function that handles this automatically, called <code>bundle_install_wrapper()</code>. It first tries to execute the command you pass to it.
However, if Bundler exits with status code <code>7</code> (<code>GemNotFound</code>), then it will run <code>bundle install</code>. Finally, it retries the original command.</p>

<div class="highlight"><pre><code class="ruby"><span class="n">bundle_install_wrapper</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1"># Run command</span>
  <span class="nb">eval</span> <span class="s2">&quot;$@&quot;</span>
  <span class="k">if</span> <span class="o">[</span> <span class="vg">$?</span> <span class="o">=</span> <span class="mi">7</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
    <span class="c1"># If command crashes, try a bundle install</span>
    <span class="n">echo</span> <span class="o">-</span><span class="n">e</span> <span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[1;31m&#39;$@&#39; failed with exit code 7.&quot;</span>
    <span class="n">echo</span>    <span class="s2">&quot;This probably means that your system is missing gems defined in your Gemfile.&quot;</span>
    <span class="n">echo</span> <span class="o">-</span><span class="n">e</span> <span class="s2">&quot;Executing &#39;bundle install&#39;...</span><span class="se">\033</span><span class="s2">[0m&quot;</span>
    <span class="n">bundle</span> <span class="n">install</span>
    <span class="c1"># If bundle install was successful, try running command again.</span>
    <span class="k">if</span> <span class="o">[</span> <span class="vg">$?</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
      <span class="n">echo</span> <span class="s2">&quot;&#39;bundle install&#39; was successful. Retrying &#39;$@&#39;...&quot;</span>
      <span class="nb">eval</span> <span class="s2">&quot;$@&quot;</span>
    <span class="n">fi</span>
  <span class="n">fi</span>
<span class="p">}</span>
</code></pre></div>


<h2>Usage</h2>

<p>Drop the function in your <code>~/.bashrc</code>, and add aliases for rails commands:</p>

<div class="highlight"><pre><code class="ruby"><span class="k">alias</span> <span class="n">rs</span><span class="o">=</span><span class="s2">&quot;bundle_install_wrapper rails server&quot;</span>
<span class="k">alias</span> <span class="n">rc</span><span class="o">=</span><span class="s2">&quot;bundle_install_wrapper rails console&quot;</span>
<span class="c1"># etc.</span>
</code></pre></div>


<p>If you want aliases that support any Rails application, you can use something like this:</p>

<div class="highlight"><pre><code class="ruby"><span class="c1"># Run Rails commands on any version</span>
<span class="n">rails_cmd</span><span class="p">(){</span>
  <span class="c1"># Rails 3</span>
  <span class="k">if</span> <span class="o">[</span> <span class="o">-</span><span class="n">e</span> <span class="o">.</span><span class="n">/script</span><span class="o">/</span><span class="n">rails</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="n">bundle_install_wrapper</span> <span class="n">rails3_with_editor</span> <span class="vg">$@</span>
  <span class="c1"># Rails &lt;= 2</span>
  <span class="n">elif</span> <span class="o">[</span> <span class="o">-</span><span class="n">e</span> <span class="o">.</span><span class="n">/script</span><span class="o">/</span><span class="vg">$1</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="n">bundle_install_wrapper</span> <span class="o">.</span><span class="n">/script</span><span class="o">/</span><span class="vg">$@</span>
  <span class="c1"># Rails 4</span>
  <span class="n">elif</span> <span class="o">[</span> <span class="o">-</span><span class="n">e</span> <span class="o">.</span><span class="n">/config</span><span class="o">.</span><span class="n">ru</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="n">grep</span> <span class="o">-</span><span class="n">q</span> <span class="no">Rails</span> <span class="n">config</span><span class="o">.</span><span class="n">ru</span><span class="p">;</span> <span class="k">then</span> <span class="n">bundle_install_wrapper</span> <span class="n">rails</span> <span class="vg">$@</span>
  <span class="k">else</span> <span class="n">echo</span> <span class="s2">&quot;== I don&#39;t think this is a Rails application!&quot;</span>
  <span class="n">fi</span>
<span class="p">}</span>
<span class="k">alias</span>   <span class="n">rs</span><span class="o">=</span><span class="s2">&quot;rails_cmd server&quot;</span>
<span class="k">alias</span>  <span class="n">rsd</span><span class="o">=</span><span class="s2">&quot;rails_cmd server -u&quot;</span>
<span class="k">alias</span>   <span class="n">rc</span><span class="o">=</span><span class="s2">&quot;rails_cmd console&quot;</span>
<span class="k">alias</span>   <span class="n">rg</span><span class="o">=</span><span class="s2">&quot;rails_cmd generate&quot;</span>
</code></pre></div>


<p>See the <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/ruby_on_rails.sh">Ruby on Rails section in my .bashrc</a> if you&rsquo;re interested in more aliases,
and please leave a comment if you have any tips to share.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[capistrano_colors has been merged into capistrano]]></title>
    <link href="http://madebynathan.com/2012/11/08/capistrano_colors-has-been-merged-into-capistrano/"/>
    <updated>2012-11-08T06:55:17+07:00</updated>
    <id>http://madebynathan.com/2012/11/08/capistrano_colors-has-been-merged-into-capistrano</id>
    <content type="html"><![CDATA[<p><code>capistrano_colors</code> has been <a href="https://github.com/capistrano/capistrano/pull/283">merged</a> into <code>capistrano</code>. If you update <code>capistrano</code> to version <code>2.13.5</code>, you will no longer need to include <code>capistrano_colors</code> in your <code>Gemfile</code>.<br/>Don&rsquo;t forget to also remove <code>require 'capistrano_colors'</code> from <code>config/deploy.rb</code>.</p>

<p>If you&rsquo;ve been using <code>capistrano</code> without the <code>capistrano_colors</code> gem, well, you&rsquo;ve been missing out! Your logs will now be nicely formatted and colored by default, like this:</p>

<p><img src="http://madebynathan.com/images/posts/2012/11/cap_colors-resized-post.png" alt="Capistrano logs with colors and formatting" /></p>

<p>However, if you happen to be a big fan of black &amp; white logs, you can just add <code>disable_log_formatters</code> to <code>config/deploy.rb</code>. See the <a href="https://github.com/capistrano/capistrano/wiki/Formatting-Logs">Formatting Logs wiki page</a> for more information about customizing the colors and styles.</p>

<p>Thanks to <a href="https://github.com/stjernstrom">@stjernstrom</a> for creating the <code>capistrano_colors</code> gem, and to <a href="https://github.com/carsomyr">@carsomyr</a> for merging my pull request!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Auto-reloading your .bashrc (or .zshrc)]]></title>
    <link href="http://madebynathan.com/2012/10/29/auto-reloading-your-bashrc/"/>
    <updated>2012-10-29T14:31:21+07:00</updated>
    <id>http://madebynathan.com/2012/10/29/auto-reloading-your-bashrc</id>
    <content type="html"><![CDATA[<p>If you often make changes to your <code>~/.bashrc</code>, you might be sick of typing <code>source ~/.bashrc</code> after every change.
It can also be annoying when you switch to a different tab in your terminal, but your new aliases or functions aren&rsquo;t available until you type <code>source ~/.bashrc</code>.</p>

<p>While I was working on <a href="https://github.com/ndbroadbent/scm_breeze">scm_breeze</a> and my <a href="https://github.com/ndbroadbent/dotfiles">dotfiles</a> repo, I grew tired of having to type this command, so I aliased it to <code>sbrc</code>. But I knew I could do better, so I created an auto-reload script that reloads my <code>~/.bashrc</code> if there are any changes to itself, or any of the files that it loads.</p>

<p>When you run it at the beginning of your <code>.bashrc</code>, it wraps the <code>source</code> and <code>.</code> commands with a function that builds an index of all the sourced files. At the end of your <code>.bashrc</code>, you need to call the <code>finalize_auto_reload</code> function, which:</p>

<ul>
<li>Removes the <code>source</code> and <code>.</code> overrides</li>
<li>Sorts the sourced file index and removes duplicates</li>
<li>Stores the mtime of the most recently modified source file in a variable</li>
<li>Adds the <code>auto_reload_bashrc</code> function to your <code>PROMPT_COMMAND</code>.</li>
</ul>


<p>Whenever you start a new line in your terminal, the <code>auto_reload_bashrc</code> function reloads your <code>.bashrc</code> if any of the sourced files have changed. Changes are detected by looking up the most recent modification time from all of the sourced files, and comparing that time with the previous value.</p>

<p>My <code>.bashrc</code> sources 28 files from my <a href="https://github.com/ndbroadbent/dotfiles">dotfiles</a>, <a href="https://github.com/ndbroadbent/scm_breeze">scm_breeze</a>, and <a href="https://rvm.io/">RVM</a>. Running the <code>auto_reload_bashrc</code> function to check for changes only takes 11 ms.</p>

<p>If you make a lot of changes to your <code>.bashrc</code> or <code>.zsh</code>, you can check out my auto-reloading script here:
<a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/auto_reload.sh" target="_blank"><a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/auto_reload.sh">https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/auto_reload.sh</a></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Saving space in the terminal with symbols]]></title>
    <link href="http://madebynathan.com/2012/10/14/saving-space-in-the-terminal-with-symbols/"/>
    <updated>2012-10-14T16:28:47+07:00</updated>
    <id>http://madebynathan.com/2012/10/14/saving-space-in-the-terminal-with-symbols</id>
    <content type="html"><![CDATA[<p>I&rsquo;m saving a little space in my terminal by replacing my username and group (ndbroadbent) with a single symbol.
I&rsquo;m doing this <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/prompt.sh#L64-66">in my prompt</a>,
as well as in the output of <code>ls</code> commands:</p>

<p><img src="http://madebynathan.com/images/posts/2012/10/ls_with_symbols-resized-post.png" alt="ls and prompt with symbols" /></p>

<p>(My laptop&rsquo;s hostname is also represented by a symbol.)</p>

<p>For the ls output, it was a bit tricky to re-justify the username and group columns after substituting my username.
I decided to do it in ruby, and then played some ruby golf:</p>

<div class="highlight"><pre><code class="ruby"><span class="n">o</span><span class="o">=</span><span class="no">STDIN</span><span class="o">.</span><span class="n">read</span><span class="p">;</span><span class="n">re</span><span class="o">=</span><span class="sr">/^(([^ ]* +){2})(([^ ]* +){3})/</span><span class="p">;</span><span class="n">u</span><span class="p">,</span><span class="n">g</span><span class="p">,</span><span class="n">s</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">lines</span><span class="o">.</span><span class="n">map</span><span class="p">{</span><span class="o">|</span><span class="n">l</span><span class="o">|</span><span class="n">l</span><span class="o">[</span><span class="n">re</span><span class="p">,</span><span class="mi">3</span><span class="o">]</span><span class="p">}</span><span class="o">.</span><span class="n">compact</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:split</span><span class="p">)</span><span class="o">.</span><span class="n">transpose</span><span class="o">.</span><span class="n">map</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="o">|</span><span class="n">a</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:size</span><span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="o">+</span><span class="mi">1</span><span class="p">};</span><span class="nb">puts</span> <span class="n">o</span><span class="o">.</span><span class="n">lines</span><span class="o">.</span><span class="n">map</span><span class="p">{</span><span class="o">|</span><span class="n">l</span><span class="o">|</span><span class="n">l</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">re</span><span class="p">){</span><span class="o">|</span><span class="n">m</span><span class="o">|</span><span class="s2">&quot;%s%-</span><span class="si">#{</span><span class="n">u</span><span class="si">}</span><span class="s2">s %-</span><span class="si">#{</span><span class="n">g</span><span class="si">}</span><span class="s2">s%</span><span class="si">#{</span><span class="n">s</span><span class="si">}</span><span class="s2">s &quot;</span><span class="sx">%[$1,*$3.split]</span><span class="p">}}</span>
</code></pre></div>


<p>This little script parses the modified output of <code>ls -lhv</code>, calculates the max length of the user/group/size columns, and then pads those columns with the correct number of spaces.</p>

<p>My final <code>ls</code> command looks like this:</p>

<div class="highlight"><pre><code class="bash">ls -lhv --group-directories-first | sed <span class="se">\&quot;</span>s/<span class="nv">$USER</span>/<span class="se">\$</span><span class="o">(</span>/bin/cat <span class="nv">$HOME</span>/.user_sym<span class="o">)</span>/g<span class="se">\&quot;</span> | rejustify_ls_columns
</code></pre></div>


<p>(where <code>rejustify_ls_columns</code> is a function wrapping the ruby script above.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Automate your Rails development with cron: Keep projects updated, install gems, and maintain a repo index]]></title>
    <link href="http://madebynathan.com/2012/10/11/automate-your-development-machine-keep-projects-updated-install-gems-refresh-git-repo-index/"/>
    <updated>2012-10-11T08:56:54+07:00</updated>
    <id>http://madebynathan.com/2012/10/11/automate-your-development-machine-keep-projects-updated-install-gems-refresh-git-repo-index</id>
    <content type="html"><![CDATA[<p>A day in the life of a Rails developer will usually involve a few <code>git pull</code>s, <code>bundle install</code>s, and switching between different projects. I thought it would be great if my projects could be automatically kept up-to-date, so that I don&rsquo;t have to spend too much time updating code or installing new gems.</p>

<p>I&rsquo;m using the <code>whenever</code> gem to create cron tasks that:</p>

<ul>
<li>Update all my git repos from their remotes</li>
<li>Satisfy all of my Gemfile&rsquo;s dependencies</li>
<li>Cache rake and capistrano commands for tab completion</li>
<li>Fetch Travis CI build statuses to show in my terminal</li>
<li>Maintain an index of my git repos so I can quickly switch between projects, while keeping them organized</li>
</ul>


<p>For all of these tasks, I&rsquo;m using the <code>git_index</code> function provided by my <a href="https://github.com/ndbroadbent/scm_breeze">SCM Breeze</a> project. It creates an index of all your git projects by recursively scanning your code directory, and then lets you quickly jump to projects, or run batch commands for each of your repos. See my <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/#repository-index">SCM Breeze blog post for more info about the repository index</a>.</p>

<h3>Updating Git Repos</h3>

<p>Every 30 minutes I run a task that updates all of the local branches on all of my git repos. It does this as safely as possible:</p>

<ul>
<li>Doesn&rsquo;t do anything if there are any changed files in the working directory</li>
<li>Doesn&rsquo;t do anything unless remote and merge branches are explicitly configured for that branch</li>
<li>Doesn&rsquo;t do anything if it cannot &lsquo;fast-forward&rsquo; merge a branch (i.e. the current commit is not a parent of the latest commit in the remote repo)</li>
</ul>


<p>Basically, this means that it will leave you alone if you are working on a feature, or if you&rsquo;ve committed something that you haven&rsquo;t pushed yet.</p>

<p>Otherwise, it will bring your branches up-to-date and send a desktop notification:</p>

<p><img src="http://madebynathan.com/images/posts/2012/10/git_update_notify.jpg" alt="Git update notification" /></p>

<h3>Installing Gem dependencies</h3>

<p>I have a task that runs every hour to ensure that all of my gem dependencies are installed. If someone adds a new gem dependency to your project, it&rsquo;s great to have that automatically installed when the repo is automatically updated.</p>

<p>I&rsquo;m using the <code>git_index</code> function to run a script called <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bin/bundle_check_or_install">bundle_check_or_install</a> for each of my git repos. It also sends desktop notifications on update or failure, and doesn&rsquo;t do anything if the gems are already up-to-date.</p>

<p>If <code>bundle install</code> fails for any reason, it will touch a file at <code>'.skip_bundle_auto_install~</code> (and exclude that file from git by adding it to <code>.git/info/exclude</code>). Any future attempts to auto-update your gems will abort with the notification that &ldquo;Previous bundle install failed&rdquo;. This notification can be disabled if <code>.skip_bundle_auto_install~</code> contains the string &ldquo;SILENT&rdquo;. I do this when I stop caring about old projects, but don&rsquo;t want to delete or archive them.</p>

<h3>Caching Rake and Capistrano commands for tab completion</h3>

<p><code>rake -T</code> and <code>cap -T</code> can take a long time to run, so I run a task every hour to cache the available tasks for all of my projects, and I use these cached tasks to provide tab completion. The tasks in saved to files like <code>.cached_rake_tasks~</code> and <code>.cached_cap_tasks~</code>. <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/ruby_on_rails.sh#L99">Here&rsquo;s how I set up the Bash tab completion</a>.</p>

<h3>Fetching Travis CI Build Status</h3>

<p>I&rsquo;ve written about this before in my <a href="http://madebynathan.com/2012/01/30/travis-ci-status-in-shell-prompt/">Travis CI Status in Shell Prompt</a> post. Every 30 minutes I run a task to fetch build statuses for all the repos that contain a <code>.travis.yml</code> file. The status is saved in a hidden file called <code>.travis_status~</code>, and displayed in my prompt like this:</p>

<p><img src="http://madebynathan.com/images/posts/2012/01/travis_ci_prompt.png" alt="Travis CI status in prompt" /></p>

<h3>Updating Git Repo Index</h3>

<p>All of the previous tasks depend on the git repo index being up-to-date. It only takes a few seconds to scan through my code directories, so I run this task every minute.</p>

<p>This index lets me keep my code organized in different folders, while also letting me jump to different projects by name:</p>

<p><img src="http://madebynathan.com/images/posts/2011/10/source_list-resized-post.png" alt="Git Status With Shortcuts" /></p>

<hr/>


<p>If you want to set this up for yourself, you&rsquo;ll need to check out my <a href="https://github.com/ndbroadbent/scm_breeze">SCM Breeze</a> project. The <code>schedule.rb</code> that defines these tasks <a href="https://github.com/ndbroadbent/dotfiles/blob/master/schedule.rb">lives in my dotfiles repo</a>, and you can find the scripts I use in the <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bin/">/bin</a> directory.</p>

<p>Post a comment if you have any automation ideas to share!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to start a Google Group for a git project]]></title>
    <link href="http://madebynathan.com/2012/09/19/how-to-start-a-google-group-for-a-git-project/"/>
    <updated>2012-09-19T07:05:39+07:00</updated>
    <id>http://madebynathan.com/2012/09/19/how-to-start-a-google-group-for-a-git-project</id>
    <content type="html"><![CDATA[<p>GitHub is a great way to manage code for an open source project, but it doesn&rsquo;t
provide any way to send a message to all of
your watchers. This can be necessary whenever you make certain changes to your application.
For example, I recently merged a pull request in <a href="https://github.com/errbit/errbit">Errbit</a> that requires users to
run a Rake task next time they update the code. I had no way of notifying our users,
so I decided to create a Google Group mailing list for these kinds of notifications.</p>

<p>Creating a Google Group is easy (just go to <a href="https://groups.google.com">https://groups.google.com</a> and follow the prompts),
but the slightly tricky part is sending invites to everyone who&rsquo;s interested in your project.
I decided to start by inviting all the contributors to the Errbit codebase
(there&rsquo;s 73 contributors at the time of writing this post.)</p>

<p>You can get a list of contributor emails by running <code>git log --format='%ae' | sort -u</code> from
your git repo. However, Google Groups only lets you invite 10 emails at a time,
so here&rsquo;s a Bash/Zsh script that will print all of your contributor emails as CSV, in groups of 10:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">emails</span><span class="o">=(</span> <span class="k">$(</span>git log --format<span class="o">=</span><span class="s1">&#39;%ae&#39;</span> | sort -u<span class="k">)</span> <span class="o">)</span>
<span class="nv">total_groups</span><span class="o">=</span><span class="k">$((</span> <span class="k">${#</span><span class="nv">emails</span><span class="p">[@]</span><span class="k">}</span> <span class="o">/</span> <span class="m">10</span> <span class="k">))</span>

<span class="k">for</span> <span class="o">((</span><span class="nv">i</span><span class="o">=</span>0; i &lt;<span class="o">=</span> <span class="nv">$total_groups</span>; i++<span class="o">))</span>; <span class="k">do</span>
<span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;Group $((i + 1)):&quot;</span>
  <span class="nb">echo</span> <span class="s2">&quot;-------------------------------------------------------&quot;</span>
  <span class="nv">grouped_emails</span><span class="o">=(</span> <span class="k">${</span><span class="nv">emails</span><span class="p">[@]:</span><span class="k">$((</span> <span class="nv">$i</span> <span class="o">*</span> <span class="m">10</span> <span class="k">))</span><span class="p">:</span><span class="nv">10</span><span class="k">}</span> <span class="o">)</span>
  <span class="nb">printf</span> <span class="s2">&quot;%s, &quot;</span> <span class="s2">&quot;${grouped_emails[@]}&quot;</span> | cut -d <span class="s2">&quot;,&quot;</span> -f 1-<span class="k">${#</span><span class="nv">grouped_emails</span><span class="p">[@]</span><span class="k">}</span>
  <span class="nb">echo</span>
<span class="k">done</span>
</code></pre></div>


<p>After pasting this script into your terminal, you can copy and paste each batch of
emails into the <strong>Enter email addresses of people to invite</strong> textarea.
But be careful to write and save your invite message in your text editor, because if you
write it on the page you won&rsquo;t be able to get it back after sending the first batch of invites.</p>

<p>It will still be quite a tedious process since you&rsquo;ll need to enter a captcha for each batch,
but hopefully this script will save you some time.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Skype notifications using libnotify on Linux]]></title>
    <link href="http://madebynathan.com/2012/03/24/skype-notifications-using-libnotify-on-linux/"/>
    <updated>2012-03-24T17:55:18+07:00</updated>
    <id>http://madebynathan.com/2012/03/24/skype-notifications-using-libnotify-on-linux</id>
    <content type="html"><![CDATA[<p>Skype on Linux comes with it&rsquo;s own notification system. It&rsquo;s not that bad, but it&rsquo;s not consistent, either.
If you want to configure Skype to use <code>libnotify</code> instead, run the following script in your terminal:</p>

<p>(NOTE: You must have installed Skype, and logged in at least once.)</p>

<div class="highlight"><pre><code class="bash">bash &lt; &lt;<span class="o">(</span>curl -s https://raw.github.com/gist/2181122/skype-libnotify.sh<span class="o">)</span>
</code></pre></div>


<p>This downloads and executes the script from this gist: <a href="https://gist.github.com/2181122">https://gist.github.com/2181122</a></p>

<p>It fetches the skype configuration from <a href="https://github.com/ndbroadbent/dotfiles/blob/master/skype/skype-UI.xml">here</a>,
which is part of my <a href="https://github.com/ndbroadbent/dotfiles">dotfiles</a> repo.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scheduling one-off tasks with 'at']]></title>
    <link href="http://madebynathan.com/2012/02/25/scheduling-one-off-tasks-with-at-/"/>
    <updated>2012-02-25T16:00:27+07:00</updated>
    <id>http://madebynathan.com/2012/02/25/scheduling-one-off-tasks-with-at-</id>
    <content type="html"><![CDATA[<p>You might be familiar with the <a href="http://en.wikipedia.org/wiki/Cron">cron</a> job scheduler,
which is great for repeating tasks.
But when you want to schedule a command to only run once in the future,
the <a href="http://linux.die.net/man/1/at">at</a> command is what you are looking for.</p>

<p>In my case, I was updating a plugin for our
<a href="http://www.thoughtworks-studios.com/mingle-agile-project-management">Thoughtworks Mingle</a> instance,
but the update wasn&rsquo;t hugely important. Many of our staff rely on Mingle for their work,
and restarting it takes it offline for a few minutes.</p>

<p>So I used the <code>at</code> command to schedule the restart to happen at midnight, after everyone had gone home:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span><span class="nb">echo</span> <span class="s2">&quot;/etc/init.d/mingle restart&quot;</span> | at -m 00:00
job 6 at 2012-02-26 00:00
</code></pre></div>


<p>Use <code>atq</code> or <code>at -l</code> to see the list of pending jobs:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>atq
6   2012-02-26 00:00 a root
</code></pre></div>


<p>Use <code>at -c &lt;job id&gt;</code> to view the script that will be run:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>at -c 6

<span class="c">#!/bin/sh</span>
<span class="c"># atrun uid=0 gid=0</span>
<span class="c"># mail     root 1</span>
<span class="nb">umask </span>22
<span class="nv">HOSTNAME</span><span class="o">=</span>...
&lt;lots of environment variables <span class="nb">set </span>here&gt;

/etc/init.d/mingle restart
</code></pre></div>


<p>To delete a scheduled task, run <code>at -d &lt;job id&gt;</code>:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>at -d 6
<span class="nv">$ </span>atq
<span class="o">(</span>no output<span class="o">)</span>
</code></pre></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Travis CI Status in Shell Prompt]]></title>
    <link href="http://madebynathan.com/2012/01/31/travis-ci-status-in-shell-prompt/"/>
    <updated>2012-01-31T00:21:13+07:00</updated>
    <id>http://madebynathan.com/2012/01/31/travis-ci-status-in-shell-prompt</id>
    <content type="html"><![CDATA[<h3>Update:</h3>

<p>I&rsquo;ve updated the build status checking script, because updating all branches was taking too long (over 20 minutes.)
Now it performs frequent updates for the current branch, and only periodic updates for all branches.</p>

<hr />

<p><a href="http://travis-ci.org/">Travis CI</a> is a distributed <a href="http://en.wikipedia.org/wiki/Continuous_integration">continuous integration</a> service for the open source community, and it can be used with any of your public projects on <a href="https://github.com/">GitHub</a>. You&rsquo;ve probably seen some &lsquo;build status&rsquo; badges like this:</p>

<p><img src="https://secure.travis-ci.org/travis-ci/travis-ci.png" alt="Travis CI build status"></p>

<p>Wouldn&rsquo;t it be cool if you could see that build status in your shell prompt whenever you are working on a project?</p>

<p>Here&rsquo;s what my shell prompt looks like now:</p>

<p><img src="http://madebynathan.com/images/posts/2012/01/travis_ci_prompt.png" alt="Travis CI status in prompt" /></p>

<p>This shows the build status for the current branch.</p>

<hr />

<p>You will need to cache the build status, since looking it up takes a few seconds.</p>

<p>You should use my fork of <a href="https://github.com/mislav">mislav&rsquo;s</a> <code>travis-ci</code> script, which can check the build status of a project. Make sure <code>~/bin</code> is in your <code>PATH</code>, and if you are using RVM, make sure you are using your default ruby.</p>

<p>Run the following to install it:</p>

<div class="highlight"><pre><code class="bash">mkdir -p ~/bin/
curl -sL https://raw.github.com/gist/1708408/travis.rb &gt; ~/bin/travis-ci <span class="se">\</span>
  <span class="o">&amp;&amp;</span> chmod +x ~/bin/travis-ci

gem install hub | tail -2
ruby -e <span class="s1">&#39;require &quot;json&quot;&#39;</span> 2&gt;/dev/null <span class="o">||</span> gem install json
</code></pre></div>


<p>Next, we need to update the cached status.
The following code is included as part of my <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/">SCM Breeze project</a>, but feel free to save the <code>update_travis_ci_status</code> script <a href="#update_travis_ci_status">at the bottom of this post [1]</a> to <code>/usr/bin/update_travis_ci_status</code>.</p>

<p>We will also need a way to run this update task every few minutes, across all of our local git repos.
We only want to frequently update the status for the currently checked out branch, and periodically update the status for all branches.</p>

<p>The <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/">SCM Breeze project</a> also maintains an index of your git repositories, which gives you the ability to run batch commands via the <code>git_index</code> function.
So the build status update can be easily set up as a cron task:</p>

<div class="highlight"><pre><code class="text">*/5 * * * * /bin/bash -c &#39;. $HOME/.bashrc &amp;&amp; git_index --rebuild &amp;&amp; git_index --batch-cmd update_travis_ci_status&#39;
*/45 * * * * /bin/bash -c &#39;. $HOME/.bashrc &amp;&amp; git_index --rebuild &amp;&amp; export UPDATE_ALL_BRANCHES=true &amp;&amp; git_index --batch-cmd update_travis_ci_status&#39;
</code></pre></div>


<p>Alternatively, you could save the following script to <code>/usr/bin/update_all_travis_ci_statuses</code>.</p>

<div class="highlight"><pre><code class="bash"><span class="c">#!/bin/bash</span>
<span class="c"># (Replace `$HOME/code` with the location of your projects)</span>
<span class="k">for </span>f in find <span class="s2">&quot;$HOME/code&quot;</span> -maxdepth 4 -name .travis.yml; <span class="k">do</span>
  <span class="o">(</span><span class="nb">builtin cd</span> <span class="s2">&quot;$(dirname $f)&quot;</span> <span class="o">&amp;&amp;</span> update_travis_ci_status<span class="o">)</span>
<span class="k">done</span>
</code></pre></div>


<p>&hellip; and use the following cron task:</p>

<div class="highlight"><pre><code class="text">*/5 * * * * /bin/bash -c &#39;. $HOME/.bashrc &amp;&amp; /usr/bin/update_all_travis_ci_statuses&#39;
*/45 * * * * /bin/bash -c &#39;. $HOME/.bashrc &amp;&amp; export UPDATE_ALL_BRANCHES=true &amp;&amp; /usr/bin/update_all_travis_ci_statuses&#39;
</code></pre></div>


<p>(you need to source your <code>.bashrc</code> if your default ruby comes from RVM)</p>

<p>Finally, you need a way to display the cached status in your prompt.</p>

<p>Here are the functions I use to return a colored pass / fail / running symbol:</p>

<div class="highlight"><pre><code class="bash"><span class="c"># Returns the Travis CI status for a github project</span>
parse_travis_status<span class="o">()</span> <span class="o">{</span>
  <span class="nb">local </span><span class="nv">branch</span><span class="o">=</span><span class="s2">&quot;$1&quot;</span>
  <span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;$branch&quot;</span> <span class="o">]</span>; <span class="k">then </span><span class="nv">branch</span><span class="o">=</span><span class="s2">&quot;master&quot;</span>; <span class="k">fi</span>

<span class="k">  </span><span class="nb">local </span><span class="nv">stat_file</span><span class="o">=</span><span class="k">$(</span>find_in_cwd_or_parent <span class="s2">&quot;.travis_status~&quot;</span><span class="k">)</span>
  <span class="k">if</span> <span class="o">[</span> -e <span class="s2">&quot;$stat_file&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">    case</span> <span class="s2">&quot;$(grep -m 1 &quot;</span>^<span class="nv">$branch</span> <span class="s2">&quot; &quot;</span><span class="nv">$stat_file</span><span class="s2">&quot;)&quot;</span> in
    *passed<span class="o">)</span>  <span class="nb">echo</span> <span class="s2">&quot;\[\e[01;32m\]✔ &quot;</span>;; <span class="c"># green</span>
    *failed<span class="o">)</span>  <span class="nb">echo</span> <span class="s2">&quot;\[\e[01;31m\]✘ &quot;</span>;; <span class="c"># red</span>
    *running<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&quot;\[\e[01;33m\]⁇ &quot;</span>;; <span class="c"># yellow</span>
    <span class="k">esac</span>
<span class="k">  fi</span>
<span class="o">}</span>

<span class="c"># Test whether file exists in current or parent directories</span>
find_in_cwd_or_parent<span class="o">()</span> <span class="o">{</span>
  <span class="nb">local </span><span class="nv">slashes</span><span class="o">=</span><span class="k">${</span><span class="nv">PWD</span><span class="p">//[^\/]/</span><span class="k">}</span>; <span class="nb">local </span><span class="nv">directory</span><span class="o">=</span><span class="nv">$PWD</span>;
  <span class="k">for</span> <span class="o">((</span> <span class="nv">n</span><span class="o">=</span><span class="k">${#</span><span class="nv">slashes</span><span class="k">}</span>; n&gt;0; --n <span class="o">))</span>; <span class="k">do</span>
<span class="k">    </span><span class="nb">test</span> -e <span class="nv">$directory</span>/<span class="nv">$1</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s2">&quot;$directory/$1&quot;</span> <span class="o">&amp;&amp;</span> <span class="k">return </span>0
    <span class="nv">directory</span><span class="o">=</span><span class="nv">$directory</span>/..
  <span class="k">done</span>
<span class="k">  return </span>1
<span class="o">}</span>
</code></pre></div>


<p>(it also works if you are in a project&rsquo;s sub-directory.)</p>

<p>Finally, add <code>$(parse_travis_status "$current_branch")</code> somewhere in your <code>$PS1</code>. You should set the <code>$current_branch</code> variable to the current git branch, but it defaults to the <code>master</code> branch if you leave it blank.</p>

<p>You may like to have a look at the <a href="https://github.com/ndbroadbent/dotfiles/blob/master/bashrc/prompt.sh">prompt section of my dotfiles</a>, to see how I do it.</p>

<p>Enjoy! Please let me know if you have any questions, or need some help.</p>

<hr />

<p><a name="update_travis_ci_status">[1]</a> <code>update_travis_ci_status</code> script:</p>

<div class="highlight"><pre><code class="bash"><span class="c">#!/bin/bash</span>
<span class="k">if</span> <span class="o">[</span> -e <span class="s2">&quot;.travis.yml&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">  if </span><span class="nb">type </span>ruby &gt; /dev/null 2&gt;&amp;1 <span class="o">&amp;&amp;</span> <span class="nb">type </span>travis-ci &gt; /dev/null 2&gt;&amp;1; <span class="k">then</span>
<span class="k">    </span><span class="nb">local </span><span class="nv">stat_file</span><span class="o">=</span><span class="s2">&quot;.travis_status~&quot;</span>
    <span class="nb">local </span><span class="nv">tmp_stat_file</span><span class="o">=</span><span class="s2">&quot;$stat_file&quot;&quot;.tmp&quot;</span>

    <span class="c"># Either update all branches, or only current branch</span>
    <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$UPDATE_ALL_BRANCHES&quot;</span> <span class="o">=</span> <span class="s2">&quot;true&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">      </span><span class="nb">local </span><span class="nv">all_branches</span><span class="o">=</span><span class="k">$(</span><span class="se">\g</span>it branch -a<span class="k">)</span>
      <span class="c"># All branches on origin remote that have local copies</span>
      <span class="nb">local </span><span class="nv">branches</span><span class="o">=</span><span class="k">$(</span>comm -12 &lt;<span class="o">(</span><span class="nb">echo</span> <span class="s2">&quot;$all_branches&quot;</span> | <span class="se">\</span>
                                  sed <span class="s2">&quot;s/ *remotes\/origin\///;tm;d;:m;/^HEAD/d;&quot;</span> | sort<span class="k">)</span> <span class="se">\</span>
                                &lt;<span class="o">(</span><span class="nb">echo</span> <span class="s2">&quot;$all_branches&quot;</span> | <span class="se">\</span>
                                  sed <span class="s2">&quot;/ *remotes\//d;s/^[\* ]*//&quot;</span> | sort<span class="o">))</span>
      <span class="c"># Create a new, blank temp file</span>
      <span class="nb">echo</span> -n &gt; <span class="s2">&quot;$tmp_stat_file&quot;</span>
    <span class="k">else</span>
      <span class="c"># Only current branch</span>
      <span class="nb">local </span><span class="nv">branches</span><span class="o">=</span><span class="s2">&quot;$(\git branch 2&gt; /dev/null | sed &quot;</span>s/^<span class="se">\*</span> <span class="se">\(</span><span class="o">[</span>^ <span class="o">]</span>*<span class="se">\)</span>/<span class="se">\1</span>/;tm;d;:m<span class="s2">&quot;)&quot;</span>
      <span class="c"># Copy current file to temp file</span>
      touch <span class="s2">&quot;$stat_file&quot;</span>
      cp -f <span class="s2">&quot;$stat_file&quot;</span> <span class="s2">&quot;$tmp_stat_file&quot;</span>
    <span class="k">fi</span>

<span class="k">    for </span>branch in <span class="nv">$branches</span>; <span class="k">do</span>
<span class="k">      </span><span class="nb">local </span><span class="nv">travis_output</span><span class="o">=</span><span class="k">$(</span>travis-ci <span class="s2">&quot;$branch&quot;</span> 2&gt;&amp;1<span class="k">)</span>
      <span class="nb">local </span><span class="nv">status</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
      <span class="k">case</span> <span class="s2">&quot;$travis_output&quot;</span> in
      *built<span class="se">\ </span>OK*<span class="o">)</span>    <span class="nv">status</span><span class="o">=</span><span class="s2">&quot;passed&quot;</span>;;
      *failed*<span class="o">)</span>       <span class="nv">status</span><span class="o">=</span><span class="s2">&quot;failed&quot;</span>;;
      *in<span class="se">\ </span>progress*<span class="o">)</span> <span class="nv">status</span><span class="o">=</span><span class="s2">&quot;running&quot;</span>;;
      <span class="k">esac</span>

      <span class="c"># If branch has a build status</span>
      <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&quot;$status&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">        if </span>grep -q <span class="s2">&quot;^$branch&quot;</span> <span class="s2">&quot;$tmp_stat_file&quot;</span>; <span class="k">then</span>
          <span class="c"># Replace branch&#39;s build status</span>
          sed -e <span class="s2">&quot;s/^$branch .*/$branch $status/&quot;</span> -i <span class="s2">&quot;$tmp_stat_file&quot;</span>
        <span class="k">else</span>
          <span class="c"># Append new line for branch</span>
          <span class="nb">echo</span> <span class="s2">&quot;$branch $status&quot;</span> &gt;&gt; <span class="s2">&quot;$tmp_stat_file&quot;</span>
        <span class="k">fi</span>
<span class="k">      fi</span>
<span class="k">    done</span>

    <span class="c"># Replace current stat file with finished update</span>
    mv -f <span class="s2">&quot;$tmp_stat_file&quot;</span> <span class="s2">&quot;$stat_file&quot;</span>
    <span class="c"># Ignore status file from git repo</span>
    <span class="k">if</span> ! <span class="o">([</span> -e .git/info/exclude <span class="o">]</span> <span class="o">&amp;&amp;</span> grep -q <span class="s2">&quot;$stat_file&quot;</span> .git/info/exclude<span class="o">)</span>; <span class="k">then</span>
<span class="k">      </span><span class="nb">echo</span> <span class="s2">&quot;$stat_file&quot;</span> &gt;&gt; .git/info/exclude
    <span class="k">fi</span>
<span class="k">  fi</span>
<span class="k">fi</span>
</code></pre></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing Multiple Databases for a Rails app on Travis CI]]></title>
    <link href="http://madebynathan.com/2011/12/13/testing-multiple-databases-for-a-rails-app-on-travis-ci/"/>
    <updated>2011-12-13T22:12:50+07:00</updated>
    <id>http://madebynathan.com/2011/12/13/testing-multiple-databases-for-a-rails-app-on-travis-ci</id>
    <content type="html"><![CDATA[<p>I&rsquo;m currently doing a lot of work on an open source Ruby on Rails project called <a href="http://fatfreecrm.com/">Fat Free CRM</a>.
The code is hosted on <a href="https://github.com/fatfreecrm/fat_free_crm">github</a>, and we are using the amazing continuous integration
service provided by <a href="http://travis-ci.org/#!/fatfreecrm/fat_free_crm">Travis CI</a>.</p>

<p><a href="http://about.travis-ci.org/">Find out more about Travis CI here.</a></p>

<p>We&rsquo;ve been working on some powerful features for Fat Free CRM, such as dynamic custom fields,
and we wanted to make sure that they work across all of our supported databases.
So here&rsquo;s how I set up our Travis CI build matrix to test multiple databases,
with some help from the <a href="http://about.travis-ci.org/docs/user/database-setup/">Travis docs</a>:</p>

<h3>.travis.yml</h3>

<p>We add the databases to our build matrix by setting ENV variables. Add the following lines to your <code>.travis.yml</code>:</p>

<div class="highlight"><pre><code class="ruby"><span class="ss">env</span><span class="p">:</span>
  <span class="o">-</span> <span class="no">DB</span><span class="o">=</span><span class="n">mysql</span>
  <span class="o">-</span> <span class="no">DB</span><span class="o">=</span><span class="n">postgres</span>
  <span class="o">-</span> <span class="no">DB</span><span class="o">=</span><span class="n">sqlite</span>  
</code></pre></div>


<h3>Database configuration</h3>

<p>We package multiple example database configurations for each of our supported databases, like this:</p>

<ul>
<li><code>config/database.mysql.yml</code></li>
<li><code>config/database.postgres.yml</code></li>
<li><code>config/database.sqlite.yml</code></li>
</ul>


<p>We also have a rake task that is a prequisite for the <code>spec</code> task, and this sets up the example configuration files for Travis.</p>

<p>It copies the <code>database.yml</code> template specified by our <code>DB</code> variable, using postgres as the default.</p>

<div class="highlight"><pre><code class="ruby"><span class="no">FileUtils</span><span class="o">.</span><span class="n">cp</span> <span class="s2">&quot;config/database.</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;DB&#39;</span><span class="o">]</span> <span class="o">||</span> <span class="s1">&#39;postgres&#39;</span><span class="si">}</span><span class="s2">.yml&quot;</span><span class="p">,</span> <span class="s1">&#39;config/database.yml&#39;</span>
</code></pre></div>


<h3>Gemfile.ci</h3>

<p>I created a new Gemfile for CI. It simply tells bundler to use the gem specified by our <code>DB</code> variable,
prevents any other database gems from being loaded, and then loads the &lsquo;real&rsquo; Gemfile.</p>

<p>Here&rsquo;s the contents of <code>Gemfile.ci</code>:</p>

<div class="highlight"><pre><code class="ruby"><span class="k">case</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;DB&#39;</span><span class="o">]</span>
<span class="k">when</span> <span class="s2">&quot;mysql&quot;</span><span class="p">;</span> <span class="n">gem</span> <span class="s2">&quot;mysql2&quot;</span><span class="p">,</span> <span class="s2">&quot;0.3.10&quot;</span>
<span class="k">when</span> <span class="s2">&quot;sqlite&quot;</span><span class="p">;</span> <span class="n">gem</span> <span class="s2">&quot;sqlite3&quot;</span> 
<span class="k">when</span> <span class="s2">&quot;postgres&quot;</span><span class="p">;</span> <span class="n">gem</span> <span class="s2">&quot;pg&quot;</span><span class="p">,</span> <span class="s2">&quot;&gt;= 0.9.0&quot;</span>
<span class="k">end</span>

<span class="k">def</span> <span class="nf">gem</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
  <span class="c1"># Override &#39;gem&#39; method to block any other database gems in the &#39;real&#39; Gemfile</span>
  <span class="k">super</span> <span class="k">unless</span> <span class="sx">%w(pg sqlite3 mysql2)</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">first</span><span class="p">)</span>
<span class="k">end</span>

<span class="c1"># Eval Gemfile</span>
<span class="nb">eval</span><span class="p">(</span><span class="no">IO</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">),</span> <span class="s1">&#39;Gemfile&#39;</span><span class="p">)),</span> <span class="nb">binding</span><span class="p">)</span> 
</code></pre></div>


<p>That&rsquo;s all there is to it.</p>

<hr />

<p>This is a slightly unrelated topic, but I had a lot of trouble getting our new <code>Gemfile.ci</code> to work properly.
After a serious headache, I figured out that we hadn&rsquo;t updated <code>config/boot.rb</code>
to the latest version after our upgrade.
This new <code>boot.rb</code> had a very subtle difference, and contained the following line:</p>

<div class="highlight"><pre><code class="ruby"><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BUNDLE_GEMFILE&#39;</span><span class="o">]</span> <span class="o">||=</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s1">&#39;../../Gemfile&#39;</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span>
</code></pre></div>


<p>instead of:</p>

<div class="highlight"><pre><code class="ruby"><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BUNDLE_GEMFILE&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">gemfile</span>
</code></pre></div>


<p>Notice the <code>||=</code>, which meant that the <code>BUNDLE_GEMFILE</code> variable could actually have an effect when it was set by Travis.</p>

<p>You might have found this post if you are googling for <code>Could not find multi_json-1.0.3 in any of the sources</code>, which is
the symptom that I was experiencing (due to an updated gem and an outdated <code>Gemfile.lock</code>).
In that case, you may need to update your <code>config/boot.rb</code> to <a href="https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/app/templates/config/boot.rb">the latest version from Rails</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Managing Project Design Assets For Git Repositories: A Simple Solution]]></title>
    <link href="http://madebynathan.com/2011/10/21/managing-project-design-assets-for-git-repositories/"/>
    <updated>2011-10-21T22:25:47+07:00</updated>
    <id>http://madebynathan.com/2011/10/21/managing-project-design-assets-for-git-repositories</id>
    <content type="html"><![CDATA[<p>When you&rsquo;re creating logos or icons for a project that uses <code>git</code>,
have you ever wondered where you should store those <code>.psd</code> or <code>.xcf</code> files?
Do you commit all of your raw design files, or does it put you off that any changes to those files
will bloat your repository?</p>

<p>The following post describes a part of my <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/">SCM Breeze</a>
project. If you haven&rsquo;t seen it already, take a look at my <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/">blog post that describes what it can do</a>.</p>

<p>Here were my goals when I set out to find a solution:</p>

<ul>
<li>I wanted a design directory for each of my projects</li>
<li>I didn&rsquo;t want the design directory to be checked in to the git repository</li>
<li>The design directory needed to be synchronized across all of my machines</li>
</ul>


<p>I decided that I would need to store all of my design files in one place so that they could be easily
synchronized, and I would create symlinks from each project to the root design directory.</p>

<p>The simplest way for me to synchronize files was via my Dropbox account.
However, if you work with a larger team, you could set up a shared design directory on one
of your servers and synchronize it with <code>rsync</code>.</p>

<p>Either way, here&rsquo;s how you can effectively manage your design assets for git projects:</p>

<h2>1) Install SCM Breeze</h2>

<p>This gives you the <code>design()</code> function, as well as a bunch of other features that you can <a href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/">read about here</a>.</p>

<p>To install, run:</p>

<div class="highlight"><pre><code class="bash">git clone git://github.com/ndbroadbent/scm_breeze.git ~/.scm_breeze
~/.scm_breeze/install.sh
<span class="nb">source</span> ~/.bashrc   <span class="c"># or source ~/.zshrc</span>
</code></pre></div>


<h2>2) Create and configure a root design directory</h2>

<p>I created my root design directory at <code>~/Dropbox/Design</code>.</p>

<p>After you&rsquo;ve created your root design directory, edit <code>~/.scmbrc</code> and set <code>root_design_dir</code>
to the directory you just created.
You can also configure the design directory that&rsquo;s created in each of your projects
(default: <code>design_assets</code>), as well as the subdirectories you would like to use.
The default base subdirectories are: Images, Backgrounds, Logos, Icons, Mockups, and Screenshots.</p>

<p>After you have changed these settings, remember to run <code>source ~/.bashrc</code> or <code>source ~/.zshrc</code>.</p>

<h2>3) Initialize design directories for your projects</h2>

<p>To set up the design directories and symlinks, go to a project&rsquo;s directory and run:</p>

<div class="highlight"><pre><code class="bash">design init
</code></pre></div>


<p>If your root directory is <code>~/Dropbox/Design</code>, directories will be created at
<code>~/Dropbox/Design/projects/my_project/Backgrounds</code>, <code>~/Dropbox/Design/projects/my_project/Icons</code>, etc.</p>

<p>It will then symlink the project from your root design directory into your project&rsquo;s design directory,
so you end up with:</p>

<ul>
<li><code>my_project/design_assets</code> &ndash;> <code>~/Dropbox/Design/projects/my_project</code></li>
</ul>


<p>It also adds this directory to <code>.git/info/exclude</code> so that git ignores it.</p>

<p>Here&rsquo;s the awesome part: If you use the SCM Breeze git repository index,
you can run the following batch command to set up these directories for all of your git repos at once:</p>

<div class="highlight"><pre><code class="bash">git_index --batch-cmd design init
</code></pre></div>


<p>If you want to remove any empty design directories, run:</p>

<div class="highlight"><pre><code class="bash">design trim
</code></pre></div>


<p>And if you want to remove all of a project&rsquo;s design directories, even if they contain files:</p>

<div class="highlight"><pre><code class="bash">design rm
</code></pre></div>


<h2>4) Link existing design directories into your projects</h2>

<p>If you&rsquo;ve set up your design directories on one machine, you&rsquo;ll want them
to be synchronized across all of your other development machines.</p>

<p>Just run the following command on your other machines after following steps 1 and 2:</p>

<div class="highlight"><pre><code class="bash">design link
</code></pre></div>


<p>This uses your git index (from SCM Breeze) to figure out where to create the symlinks.
If you don&rsquo;t use the git index, the same outcome could be achieved by running &lsquo;design init&rsquo;
for each of the projects.</p>

<h2>Enjoy!</h2>

<p>Please leave a comment on this blog post if you have any questions.
If you find a bug, or it doesn&rsquo;t work quite right on your operating system,
<a href="https://github.com/ndbroadbent/scm_breeze/issues">please raise an issue on Github</a>.</p>

<h2>Shameless Dropbox Referral</h2>

<p>If you don&rsquo;t already use Dropbox, <a href="http://db.tt/hN3mN1W">click here to sign up!</a> It&rsquo;s an awesome service!
And if you sign up via that referral link, you&rsquo;ll be giving me a little extra free space :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[10 Reasons why Hackers should Jailbreak their iPhones]]></title>
    <link href="http://madebynathan.com/2011/10/20/10-reasons-why-hackers-should-jailbreak-their-iphones/"/>
    <updated>2011-10-20T17:55:18+07:00</updated>
    <id>http://madebynathan.com/2011/10/20/10-reasons-why-hackers-should-jailbreak-their-iphones</id>
    <content type="html"><![CDATA[<p>There was a post on the front page of <a href="http://news.ycombinator.com/">Hacker News</a> recently, titled &ldquo;<a href="http://raphaelcaixeta.com/blog/2012/07/09/making-chrome-better-on-ios/">Making Chrome better on iOS</a>&rdquo;. Google&rsquo;s Chrome browser is now available on iOS, and the author of the article was talking about how app developers could be persuaded to add some code to their apps which would allow Chrome to open links.</p>

<p>Restrictions like this (not being able to change your default browser) are one of the many reasons why I wouldn&rsquo;t buy another iPhone if it couldn&rsquo;t be jailbroken.
It also seems strange that &lsquo;Hacker News&rsquo; readers don&rsquo;t appear to be very excited about &lsquo;hacking&rsquo; the incredible device in their pockets.</p>

<p>We don&rsquo;t need to ask developers to support Chrome when we can just change the default browser ourselves:</p>

<p><img src="http://madebynathan.com/images/posts/2012/07/browser_changer.png" alt="Changing Default Browser" /></p>

<p>You can find the &ldquo;<a href="http://cydia.saurik.com/package/jp.tom-go.openopera">Browser Changer</a>&rdquo; package on <a href="http://cydia.saurik.com/">Cydia</a>.</p>

<p><strong>Here&rsquo;s 9 other reasons why a jailbroken iPhone is better than any other mobile device:</strong></p>

<hr/>


<h3>Grooveshark</h3>

<p>The Grooveshark iPhone app was removed from the App Store, so you can only install it on a jailbroken iPhone through Cydia.</p>

<p><img src="http://madebynathan.com/images/posts/2012/07/grooveshark.png" alt="Grooveshark" /></p>

<p>The &lsquo;Grooveshark Anywhere&rsquo; plan is required if you want to download unlimited albums and songs to play offline, but it&rsquo;s well worth the $9 per month.
It&rsquo;s definitely a replacement for iTunes, so it&rsquo;s no wonder that Apple feels threatened.</p>

<p><small>Note: I also tried Spotify for a week when it was released to New Zealand, but I found that Grooveshark has a much bigger music collection.</small></p>

<hr/>


<h3>SSH</h3>

<p>Having SSH access to your phone opens up a lot of possibilities. For example, I use <a href="https://github.com/capistrano/capistrano/wiki/">capistrano</a> to deploy iPhone apps and Cydia packages while I&rsquo;m developing them.
I can also SFTP into the iPhone&rsquo;s filesystem, and use Ubuntu&rsquo;s file browser to copy and paste files.</p>

<hr/>


<h3>VLC media player</h3>

<p>Plays anything you can transfer to your iPhone. Another great app rejected from the App Store.</p>

<hr/>


<h3>Mobile Terminal</h3>

<p>It&rsquo;s pretty neat to have a terminal on your phone, even if I don&rsquo;t use it very often.
You never know when you might need to restart or rollback a remote server:</p>

<p><img src="http://madebynathan.com/images/posts/2012/07/terminal.png" alt="Terminal" /></p>

<hr/>


<h3>SBSettings</h3>

<p>This is an incredibly useful shortcuts menu, displayed by swiping the status bar:</p>

<p><img src="http://madebynathan.com/images/posts/2012/07/sbsettings.png" alt="SBSettings" /></p>

<p>The AutoLock control is really handy when using the Maps application. I use Maps as the GPS for my car, and I don&rsquo;t want the screen to turn off while I&rsquo;m driving.</p>

<hr/>


<h3>MyWi &ndash; 3G tethering</h3>

<p>I bought the MyWi package while using a 3GS. It&rsquo;s pretty expensive at $19.99,
but it was a lifesaver when I was living without DSL for a few weeks.
I&rsquo;m still using it after getting a 4S, since iOS 5&rsquo;s &lsquo;personal hotspot&rsquo; feature was a bit flaky.
MyWi is rock-solid, and can display a small icon instead of taking over the entire status bar like the iOS hotspot.</p>

<hr/>


<h3>5 columns for icons</h3>

<p>This is just my personal preference, but I like having 5 icons in my dock and home screen.</p>

<p><img src="http://madebynathan.com/images/posts/2012/07/five-icons.png" alt="Five Icons" /></p>

<hr/>


<h3>Compiling and installing any open source iPhone apps</h3>

<p>No $99 developer license required. One example is the <a href="https://github.com/c99koder/lastfm-iphone">Last.FM</a> app, which is open source, but not available in NZ or HK iTunes stores.
Here&rsquo;s a decent list of some other <a href="http://maniacdev.com/2010/06/35-open-source-iphone-app-store-apps-updated-with-10-new-apps/">open source iPhone apps</a>.</p>

<hr/>


<h3>Script anything</h3>

<p>Finally, and perhaps most importantly, it&rsquo;s just awesome to be able to script the phone to do whatever I want.
For example, I can make the iPhone <a href="http://madebynathan.com/2011/07/20/automatically-change-iphone-wallpaper-every-30-minutes/">change the wallpaper every 30 minutes</a>, <a href="http://madebynathan.com/2010/12/26/ios-tweak-replace-operator-with-current-prepaid-balance/">show my prepaid balance in the status bar</a>, or <a href="https://github.com/ndbroadbent/quickscrollplus">scroll up and down a page when it tilts</a>.</p>

<h2>Conclusion</h2>

<p>Jailbroken iPhones FTW.</p>

<p>Please leave a comment if you have any tips to share!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git Shortcuts Like You've Never Seen Before]]></title>
    <link href="http://madebynathan.com/2011/10/19/git-shortcuts-like-youve-never-seen-before/"/>
    <updated>2011-10-19T00:14:01+07:00</updated>
    <id>http://madebynathan.com/2011/10/19/git-shortcuts-like-youve-never-seen-before</id>
    <content type="html"><![CDATA[<h2>Introducing &lsquo;SCM Breeze&rsquo;</h2>

<p><strong>SCM Breeze</strong> is a set of shell scripts (for <code>bash</code> and <code>zsh</code>) that enhance your interaction with tools
such as git. It integrates with your shell to give you numbered file shortcuts,
a repository index with tab completion, and a community driven collection of useful SCM functions.</p>

<p>Disclaimer: <strong>git</strong> is currently the only supported SCM.
I&rsquo;ve kept the project&rsquo;s name open because it won&rsquo;t be difficult to port it for other SCMs.</p>

<h2>File Shortcuts</h2>

<p>SCM Breeze makes it really easy to work with changed files, and groups of changed files.
Whenever you view your SCM status, each modified path is stored in a numbered environment variable.
You can configure the variable prefix, which is &lsquo;e&rsquo; by default.</p>

<h3><code>git_status_shortcuts</code>:</h3>

<div class="centered">
<img src="http://madebynathan.com/images/posts/2011/10/status_with_shortcuts-resized-post.png" width="590" alt="Git Status With Shortcuts" />
</div>


<br/><br/>


<p>These numbers (or ranges of numbers) can be used with any SCM or system command.</p>

<p>For example, if <code>ga</code> was your alias for <code>git add</code>, instead of typing something like:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>ga assets/git_breeze/config* assets/git_breeze/install.sh
</code></pre></div>


<p>You can type this instead:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>ga <span class="nv">$e2</span> <span class="nv">$e3</span> <span class="nv">$e11</span>
</code></pre></div>


<p>But SCM Breeze aliases <code>ga</code> to the <code>git_add_shorcuts</code> function,
which is smart enough to expand integers and ranges, so all you need to type is:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>ga 2 3 11
</code></pre></div>


<p>And if you want to add all unstaged changes (files 1 to 10):</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>ga 1-10
</code></pre></div>


<p>(Note that <code>ga</code> will also remove deleted files, unlike the standard <code>git add</code> command.
This behaviour can be turned off if you don&rsquo;t like it.)</p>

<p>You can also diff, reset or checkout a file by typing:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>gd 3
<span class="nv">$ </span>grs 4
<span class="nv">$ </span>gco 5
</code></pre></div>


<p>You can use these shortcuts with system commands by passing your command through <code>exec_git_expand_args</code>
(default alias is &lsquo;ge&rsquo;):</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span><span class="nb">echo</span> <span class="nv">$e4</span>
<span class="c"># =&gt; assets/git_breeze/git_breeze.sh</span>
<span class="nv">$ </span>ge <span class="nb">echo </span>4
<span class="c"># =&gt; assets/git_breeze/git_breeze.sh</span>
<span class="nv">$ </span>ge <span class="nb">echo </span>1-3
<span class="c"># expands to echo $e1 $e2 $e3</span>
<span class="c"># =&gt; _shared.sh assets/git_breeze/config.example.sh assets/git_breeze/config.sh</span>
</code></pre></div>


<h2>Keyboard bindings (disabled by default)</h2>

<p>My most common git commands are <code>git status</code>, <code>git add</code> and <code>git commit</code>, so I wanted these
to be as streamlined as possible. One way of speeding up commonly used commands is by binding them to
keyboard shortcuts.</p>

<p>Keyboard shortcuts are turned off by default,
but here are the default key bindings if you enable them:</p>

<ul>
<li><code>CTRL</code>+<code>SPACE</code> => <code>git_status_shortcuts</code> &ndash; show git status with file shortcuts</li>
<li><code>CTRL</code>+<code>x</code> <code>c</code> => <code>git_add_and_commit</code> &ndash; add given files (if any), then commit staged changes</li>
<li><code>CTRL</code>+<code>x</code> <code>SPACE</code> => <code>git_commit_all</code> &ndash; commit everything</li>
</ul>


<p>The commit shortcuts use the <code>git_commit_prompt</code> function, which gives a simple prompt like this:</p>

<div class="centered">
<img src="http://madebynathan.com/images/posts/2011/10/git_commit_all-resized-post.png" alt="Git Commit All" />
</div>


<br/>


<p>(When using bash, this commit prompt gives you access to your bash history via the arrow keys.)</p>

<br/>


<p>And if you really want to speed up your workflow, you can type this:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>2 3 &lt;CTRL+x c&gt;
</code></pre></div>


<p>This sends the <code>HOME</code> key, followed by <code>git_add_and_commit</code>:</p>

<div class="centered">
<img src="http://madebynathan.com/images/posts/2011/10/git_add_and_commit_params-resized-post.png" alt="Git Add And Commit" />
</div>


<br/>




<h2 id="repository-index">Repository Index</h2>


<p>The second feature is a repository index for all of your projects and submodules.
This gives you super-fast switching between your project directories, with tab completion,
and it can even tab-complete down to project subdirectories.
This means that you can keep your projects organized in subfolders,
but switch between them as easily as if they were all in one folder.</p>

<p>It&rsquo;s similar to <a href="https://github.com/joelthelion/autojump">autojump</a>, but it doesn&rsquo;t need to &lsquo;learn&rsquo; anything,
and it can do SCM-specific stuff like:</p>

<ul>
<li>Running a command for all of your repos (useful if you ever need to update a lot of remote URLs)</li>
<li>Auto-updating a repo when you switch to it and it hasn&rsquo;t been updated for at least 5 hours.</li>
</ul>


<p>The default alias for <code>git_index</code> is &rsquo;s&#8217;, which could stand for &lsquo;source&rsquo; or &lsquo;switch&rsquo; :)</p>

<p>You will first need to configure your repository directory, and then build the index:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>s --rebuild
<span class="c"># =&gt; == Scanning /home/ndbroadbent/src for git repos &amp; submodules...</span>
<span class="c"># =&gt; ===== Indexed 64 repos in /home/ndbroadbent/src/.git_index</span>
</code></pre></div>


<p>Then you&rsquo;ll be able to switch between your projects, or show the list of indexed repos:</p>

<div class="centered">
<img src="http://madebynathan.com/images/posts/2011/10/source_list-resized-post.png" alt="Git Status With Shortcuts" />
</div>


<br/><br/>


<p>To switch to a project directory, you don&rsquo;t need to type the full project name. For example,
to switch to the <code>errbit</code> project, you could type any of the following:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>s errbit
<span class="nv">$ </span>s err
<span class="nv">$ </span>s rbit
</code></pre></div>


<p>Or if you wanted to go straight to a subdirectory within <code>errbit</code>:</p>

<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>s err&lt;TAB&gt;
<span class="nv">$ </span>s errbit/&lt;TAB&gt;
<span class="c"># =&gt; app/       autotest/  config/    db/    ...</span>
<span class="nv">$ </span>s errbit/conf&lt;TAB&gt;
<span class="nv">$ </span>s errbit/config/
<span class="c"># =&gt; cd ~/src/rails/errbit/config</span>
</code></pre></div>


<h2>Anything else?</h2>

<p>If you have any awesome SCM scripts lurking in your <code>.bashrc</code> or <code>.zshrc</code>,
please feel free to send me a pull request.
It would be cool to make this project into an <a href="https://github.com/robbyrussell/oh-my-zsh">oh-my-zsh</a> for SCMs.</p>

<h1>Installation</h1>

<div class="highlight"><pre><code class="bash">git clone git://github.com/ndbroadbent/scm_breeze.git ~/.scm_breeze
~/.scm_breeze/install.sh
<span class="nb">source</span> ~/.bashrc   <span class="c"># or source ~/.zshrc</span>
</code></pre></div>


<p>(The install script simply appends the following line to your <code>.bashrc</code> or <code>.zshrc</code>):</p>

<p><code>[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] &amp;&amp; . "$HOME/.scm_breeze/scm_breeze.sh"</code></p>

<h1>Configuration</h1>

<p>SCM Breeze is configured via automatically installed <code>~/.*.scmbrc</code> files.
To change git configuration, edit <code>~/.git.scmbrc</code>.</p>

<p><strong>Note:</strong> After changing any settings, you will need to run <code>source ~/.bashrc</code> (or <code>source ~/.zshrc</code>)</p>

<p>I know we grow attached to the aliases we use every day, so I&rsquo;ve made them completely customizable.
Just change any aliases in <code>~/.git.scmbrc</code>. You can also change or remove any keyboard shortcuts.</p>

<p>Each feature is modular, so you are free to ignore the parts you don&rsquo;t want to use.
Just comment out the relevant line in <code>~/.scm_breeze/scm_breeze.sh</code>.</p>

<h1>Updating</h1>

<p>Run <code>update_scm_breeze</code>. This will update SCM Breeze from Github,
and will create or patch your <code>~/.*.scmbrc</code> files if any new settings are added.</p>

<h1>Contributing</h1>

<p>SCM Breeze lives on Github at <a href="https://github.com/ndbroadbent/scm_breeze">https://github.com/ndbroadbent/scm_breeze</a></p>

<p>Please feel free to fork and send pull requests, especially if you would like to build these features
for Mercurial, SVN, etc.</p>

<h2>Enjoy!</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git Shortcuts Like You've Never Seen Before]]></title>
    <link href="http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before/"/>
    <updated>2011-10-18T00:14:01+07:00</updated>
    <id>http://madebynathan.com/2011/10/18/git-shortcuts-like-youve-never-seen-before</id>
    <content type="html"><![CDATA[<p>This post <a href="http://madebynathan.com/2011/10/19/git-shortcuts-like-youve-never-seen-before/">has been moved</a>, redirecting you automatically in <span id="redirect-seconds">3</span> seconds&hellip;</p>

<script>
window.setInterval(function() {
  var secondsEl = $('#redirect-seconds');
  var remainingSeconds = parseInt(secondsEl.text());

  if (remainingSeconds <= 1) {
    window.location = "http://madebynathan.com/2011/10/19/git-shortcuts-like-youve-never-seen-before/";
  } else {
    secondsEl.html(--remainingSeconds);
  }
}, 1000);
</script>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A better way to use xclip (clipboard from the command line)]]></title>
    <link href="http://madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip/"/>
    <updated>2011-10-04T15:45:42+07:00</updated>
    <id>http://madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip</id>
    <content type="html"><![CDATA[<p>Sometimes you just want to copy something from your terminal and paste it somewhere else.
You might have heard of a Linux program called <code>xclip</code>, which provides a command line
interface to X selections.
However, <code>xclip</code>&rsquo;s default selection isn&rsquo;t the clipboard,
and typing <code>xclip -selection c -i ~/.ssh/id_rsa.pub<file></code> is just a bit tedious.</p>

<p>So here&rsquo;s a wrapper function that makes it less of a hassle
to integrate the clipboard with the command line.</p>

<ul>
<li>It handles input via pipe or parameters.</li>
<li>It automatically uses the contents of a file if you pass it a valid filename.</li>
<li>It prints an excerpt of what has been copied, truncated to 80 characters.</li>
</ul>


<h3>Examples</h3>

<ul>
<li>Pipe anything to the clipboard</li>
</ul>


<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>tail -n 100 /var/log/apache2/error.log | cb
<span class="c"># =&gt; Copied to clipboard: [Sun Oct 02 08:02:08 2011] [notice] Apache/2.2.17 (Ubuntu) configured -- resumin...</span>
</code></pre></div>


<ul>
<li>Copy the contents of a file to the clipboard</li>
</ul>


<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>cbf ~/.ssh/id_rsa.pub
<span class="c"># =&gt; Copied to clipboard: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnwaNIuOhZzUeR6/xEEudXt3zEh91dawhkkKx8p/+4Bw9...</span>
</code></pre></div>


<ul>
<li>Type straight into the clipboard</li>
</ul>


<div class="highlight"><pre><code class="bash"><span class="nv">$ </span>cb This is some unquoted text.
<span class="c"># =&gt; Copied to clipboard: This is some unquoted text.</span>
</code></pre></div>


<p>No options, no <code>man</code> pages.</p>

<p>It also comes with a handy <code>cb_ssh</code> alias that copies your SSH public key to the clipboard,
for when you are setting up your new <a href="https://bitbucket.org">BitBucket account</a>
with <a href="http://blog.bitbucket.org/2011/10/03/bitbucket-now-rocks-git/">unlimited, free private git repositories</a>!
I&rsquo;m not affiliated with Atlassian, I just think they&rsquo;re awesome.</p>

<p>So if you think this looks handy, you can add the following to your <code>~/.bashrc</code>:</p>

<div class="highlight"><pre><code class="bash"><span class="c"># A shortcut function that simplifies usage of xclip.</span>
<span class="c"># - Accepts input from either stdin (pipe), or params.</span>
<span class="c"># ------------------------------------------------</span>
cb<span class="o">()</span> <span class="o">{</span>
  <span class="nb">local </span><span class="nv">_scs_col</span><span class="o">=</span><span class="s2">&quot;\e[0;32m&quot;</span>; <span class="nb">local </span><span class="nv">_wrn_col</span><span class="o">=</span><span class="s1">&#39;\e[1;31m&#39;</span>; <span class="nb">local </span><span class="nv">_trn_col</span><span class="o">=</span><span class="s1">&#39;\e[0;33m&#39;</span>
  <span class="c"># Check that xclip is installed.</span>
  <span class="k">if</span> ! <span class="nb">type </span>xclip &gt; /dev/null 2&gt;&amp;1; <span class="k">then</span>
<span class="k">    </span><span class="nb">echo</span> -e <span class="s2">&quot;$_wrn_col&quot;&quot;You must have the &#39;xclip&#39; program installed.\e[0m&quot;</span>
  <span class="c"># Check user is not root (root doesn&#39;t have access to user xorg server)</span>
  <span class="k">elif</span> <span class="o">[[</span> <span class="s2">&quot;$USER&quot;</span> <span class="o">==</span> <span class="s2">&quot;root&quot;</span> <span class="o">]]</span>; <span class="k">then</span>
<span class="k">    </span><span class="nb">echo</span> -e <span class="s2">&quot;$_wrn_col&quot;&quot;Must be regular user (not root) to copy a file to the clipboard.\e[0m&quot;</span>
  <span class="k">else</span>
    <span class="c"># If no tty, data should be available on stdin</span>
    <span class="k">if</span> ! <span class="o">[[</span> <span class="s2">&quot;$( tty )&quot;</span> <span class="o">==</span> /dev/* <span class="o">]]</span>; <span class="k">then</span>
<span class="k">      </span><span class="nv">input</span><span class="o">=</span><span class="s2">&quot;$(&lt; /dev/stdin)&quot;</span>
    <span class="c"># Else, fetch input from params</span>
    <span class="k">else</span>
<span class="k">      </span><span class="nv">input</span><span class="o">=</span><span class="s2">&quot;$*&quot;</span>
    <span class="k">fi</span>
<span class="k">    if</span> <span class="o">[</span> -z <span class="s2">&quot;$input&quot;</span> <span class="o">]</span>; <span class="k">then</span>  <span class="c"># If no input, print usage message.</span>
      <span class="nb">echo</span> <span class="s2">&quot;Copies a string to the clipboard.&quot;</span>
      <span class="nb">echo</span> <span class="s2">&quot;Usage: cb &lt;string&gt;&quot;</span>
      <span class="nb">echo</span> <span class="s2">&quot;       echo &lt;string&gt; | cb&quot;</span>
    <span class="k">else</span>
      <span class="c"># Copy input to clipboard</span>
      <span class="nb">echo</span> -n <span class="s2">&quot;$input&quot;</span> | xclip -selection c
      <span class="c"># Truncate text for status</span>
      <span class="k">if</span> <span class="o">[</span> <span class="k">${#</span><span class="nv">input</span><span class="k">}</span> -gt 80 <span class="o">]</span>; <span class="k">then </span><span class="nv">input</span><span class="o">=</span><span class="s2">&quot;$(echo $input | cut -c1-80)$_trn_col...\e[0m&quot;</span>; <span class="k">fi</span>
      <span class="c"># Print status.</span>
      <span class="nb">echo</span> -e <span class="s2">&quot;$_scs_col&quot;&quot;Copied to clipboard:\e[0m $input&quot;</span>
    <span class="k">fi</span>
<span class="k">  fi</span>
<span class="o">}</span>
<span class="c"># Aliases / functions leveraging the cb() function</span>
<span class="c"># ------------------------------------------------</span>
<span class="c"># Copy contents of a file</span>
<span class="k">function </span>cbf<span class="o">()</span> <span class="o">{</span> cat <span class="s2">&quot;$1&quot;</span> | cb; <span class="o">}</span>  
<span class="c"># Copy SSH public key</span>
<span class="nb">alias </span><span class="nv">cbssh</span><span class="o">=</span><span class="s2">&quot;cbf ~/.ssh/id_rsa.pub&quot;</span>  
<span class="c"># Copy current working directory</span>
<span class="nb">alias </span><span class="nv">cbwd</span><span class="o">=</span><span class="s2">&quot;pwd | cb&quot;</span>  
<span class="c"># Copy most recent command in bash history</span>
<span class="nb">alias </span><span class="nv">cbhs</span><span class="o">=</span><span class="s2">&quot;cat $HISTFILE | tail -n 1 | cb&quot;</span>  
</code></pre></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Don't use 'bundle install {gem}'.]]></title>
    <link href="http://madebynathan.com/2011/09/03/dont-use-bundle-install-gem/"/>
    <updated>2011-09-03T03:39:22+07:00</updated>
    <id>http://madebynathan.com/2011/09/03/dont-use-bundle-install-gem</id>
    <content type="html"><![CDATA[<p>Maybe you want to update haml to the latest version. You tried to run <code>bundle install haml</code>, but now some really weird stuff is happening. Bundler decided to install all of your gems from scratch into a ./haml folder. Even when you try <code>bundle update haml</code>, the gems are still going into the ./haml folder! What&rsquo;s going on?</p>

<p><code>bundle install haml</code> is totally different from <code>bundle update haml</code>.</p>

<p>What <code>bundle install haml</code> does:</p>

<ol>
    <li>Installs all of your gems into a &#8216;haml&#8217; folder. (creates the folder if it doesn&#8217;t exist)</li>
    <li>Saves the  &#8216;haml&#8217; path in .bundle/config, so that it becomes your default gem folder for every bundle command you run in the future.</li>
</ol>


<p>If you made this mistake and want to reset everything back to normal, just run:</p>

<div class="highlight"><pre><code class="bash">rm -rf <span class="o">{</span>gem<span class="o">}</span> .bundle/config
</code></pre></div>


<p>Then, to update your gem, you should run:</p>

<div class="highlight"><pre><code class="bash">bundle update <span class="o">{</span>gem<span class="o">}</span>
</code></pre></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Running bash color codes through sed]]></title>
    <link href="http://madebynathan.com/2011/08/18/running-bash-color-codes-through-sed/"/>
    <updated>2011-08-18T03:48:59+07:00</updated>
    <id>http://madebynathan.com/2011/08/18/running-bash-color-codes-through-sed</id>
    <content type="html"><![CDATA[<p>I have a script that runs a search and replace on a git status. I recently found out how to do &#8216;git config color.status always&#8217;, so that git status gives color codes to my functions. However, this broke the substitution, and it took me a while to figure it out.</p>




<p>At the end of every line, there was an invisible &#8216;reset&#8217; color code, and this meant that &#8216;sed &#8220;s/string$/$replace&#8221;&#8217; was no longer finding &#8216;string$&#8217;.</p>




<p>Here is an example of how to use sed when your string contains color codes:</p>




<div class="highlight"><pre><code class="bash"><span class="c"># Need to strip the color character from the end of the line, otherwise</span>
<span class="c"># EOL &#39;$&#39; doesn&#39;t work. This gave me a headache for long time.</span>
<span class="c"># The echo ~&gt; regex is time-consuming, so perform a simple search first.</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nv">$line</span> <span class="o">==</span> *<span class="nv">$search</span>* <span class="o">]]</span>; <span class="k">then</span>
<span class="k">    </span><span class="nv">line</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="nv">$line</span> | sed -r <span class="s2">&quot;s:$search(\x1B\[m)?$:$replace:g&quot;</span><span class="k">)</span>
<span class="k">fi</span>
</code></pre></div>




<p>You might also find this page useful: <a href="http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed">http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed</a></p>



]]></content>
  </entry>
  
</feed>
