<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Bob Gilmore</title>
    <description>Bob Gilmore's Development Blog</description>
    <link>http://blog.bobgilmore.name</link>
    <atom:link href="http://blog.bobgilmore.name/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Trim the Fastlane Snapfile for Debugging</title>
        <description>&lt;p&gt;The default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapfile&lt;/code&gt; that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane init&lt;/code&gt; creates for you is fine, with one exception.&lt;/p&gt;

&lt;p&gt;Once you have your UI test files written, complete with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;snapshot()&lt;/code&gt; calls, you run&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane snapshot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;at the shell to generate the screenshots. But the debug cycle is way too long - it takes &lt;em&gt;forever&lt;/em&gt; to finish and show you what’s wrong. That’s because the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapfile&lt;/code&gt; runs a &lt;em&gt;bunch&lt;/em&gt; of Simulators.&lt;/p&gt;

&lt;p&gt;Do yourself a favor and restrict it to run in &lt;strong&gt;one&lt;/strong&gt; Simulator during the debugging process.&lt;/p&gt;

&lt;p&gt;To do this, I change the default devices list from the completely commented-out (and therefore ineffective) default list&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# A list of devices you want to take the screenshots from&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# devices([&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone 8&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone 8 Plus&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone SE&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone X&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPad Pro (12.9-inch)&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPad Pro (9.7-inch)&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;Apple TV 1080p&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;to a single-entry list:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# A list of devices you want to take the screenshots from&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;iPhone 8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone 8 Plus&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone SE&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPhone X&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPad Pro (12.9-inch)&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;iPad Pro (9.7-inch)&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   &quot;Apple TV 1080p&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Expand it back out to hit all Simulators after you’ve finished your basic debugging. But when you’re debugging, be sure to shrink it back down to one device type.&lt;/p&gt;

&lt;p&gt;Similarly, if your “production” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapfile&lt;/code&gt; uses multiple languages, trim the language list down while debugging.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First, trim it down to your development language and get thing working there.&lt;/li&gt;
  &lt;li&gt;Then, replace your development language with a &lt;em&gt;different&lt;/em&gt; supported language, and fix the bugs related to other languages. Trust me, you’ll have some.&lt;/li&gt;
  &lt;li&gt;Once you’re finished, expand back out to the full language list.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 18 Sep 2018 18:30:00 -0400</pubDate>
        <link>http://blog.bobgilmore.name/2018/09/18/trim-fastlane-snapfile.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2018/09/18/trim-fastlane-snapfile.html</guid>
      </item>
    
      <item>
        <title>Using the "Full" Fastlane Snapshot Install</title>
        <description>&lt;p&gt;There are two ways to install &lt;a href=&quot;https://docs.fastlane.tools/getting-started/ios/screenshots/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane snapshot&lt;/code&gt;&lt;/a&gt; in your project - a “standalone” way (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;snapshot&lt;/code&gt;-only), or as part of the &lt;a href=&quot;https://docs.fastlane.tools&quot;&gt;fastlane&lt;/a&gt; “suite” of products. The second is better, here’s why…&lt;/p&gt;

&lt;h2 id=&quot;so-so-snapshot-only&quot;&gt;So-So: Snapshot-only&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane snapshot init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;dumps your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Snapfile&lt;/code&gt; and any associated files into the top level of your project. Some day, when you want to use more fastlane tools and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fastfile&lt;/code&gt;, you’ll regret that all of the files are dumped into the project’s top level.&lt;/p&gt;

&lt;h2 id=&quot;better-part-of-the-fastlane-suite&quot;&gt;Better: Part of the fastlane suite&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and then selecting the “Automate screenshots” option creates a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane&lt;/code&gt; subdirectory in your project. All of the files (including a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fastfile&lt;/code&gt;) are created in there. As you add more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastlane&lt;/code&gt; tools to your project (and you will!), they’ll all live together there. Nice and centralized, with everything fastlane-related in the same directory as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fastfile&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;no-matter-what-you-do&quot;&gt;No matter what you do…&lt;/h2&gt;
&lt;p&gt;Move the generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SnapshotHelper.swift&lt;/code&gt; file into the appropriate target directory (probably &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*UITests&lt;/code&gt;) and include it from there.  Don’t make your UI target’s compilation rely on source code in that fastlane directory. It will &lt;em&gt;work&lt;/em&gt;, but it’s going to confuse someone, someday.&lt;/p&gt;
</description>
        <pubDate>Wed, 12 Sep 2018 18:30:00 -0400</pubDate>
        <link>http://blog.bobgilmore.name/2018/09/12/full-fastlane-snapshot-install.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2018/09/12/full-fastlane-snapshot-install.html</guid>
      </item>
    
      <item>
        <title>Testing from Working Copy</title>
        <description>&lt;p&gt;I’m doing more and more on the iPad these days, so I want to try moving to some system that lets me write and publish from here.&lt;/p&gt;

&lt;p&gt;I’m following the lead of a bunch of iOS bloggers at &lt;a href=&quot;https://www.macstories.net&quot;&gt;MacStories&lt;/a&gt;, giving &lt;a href=&quot;https://itunes.apple.com/us/app/working-copy/id896694807?mt=8&quot;&gt;Working Copy&lt;/a&gt; and &lt;a href=&quot;https://itunes.apple.com/app/pretext/id1347707000&quot;&gt;Pretext&lt;/a&gt; a try.&lt;/p&gt;

&lt;p&gt;We’ll see how this goes!&lt;/p&gt;
</description>
        <pubDate>Tue, 08 May 2018 18:00:00 -0400</pubDate>
        <link>http://blog.bobgilmore.name/2018/05/08/testing-from-working-copy.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2018/05/08/testing-from-working-copy.html</guid>
      </item>
    
      <item>
        <title>Capture Lists and Weak References</title>
        <description>&lt;p&gt;Tonight I gave a presentation at the Swift Office Hours meetup (&lt;a href=&quot;https://twitter.com/SwiftHours&quot;&gt;@SwiftHours&lt;/a&gt;) 
at Intrepid Pursuits (&lt;a href=&quot;https://twitter.com/intpd&quot;&gt;@intpd&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I talked about “Swift Closures, Capture Lists, and Weak References”.&lt;/p&gt;

&lt;p&gt;In particular, I was interested in talking about capture lists, especially how they can be used to create 
new variables in the closure.&lt;/p&gt;

&lt;p&gt;Here are the slides:&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/d/e/2PACX-1vTaawg9jm9ZCC0OLGkiL7ptCkQWbDgqjKAFxoEDlUG9knf1qUJEZG6X186GKqyXJordcvLwg5XklBVq/embed?start=false&amp;amp;loop=false&amp;amp;delayms=30000&quot; frameborder=&quot;0&quot; width=&quot;480&quot; height=&quot;299&quot; allowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
</description>
        <pubDate>Thu, 25 Jan 2018 17:00:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2018/01/25/capture-list-presentation.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2018/01/25/capture-list-presentation.html</guid>
      </item>
    
      <item>
        <title>Strong Params and Arrays of Values</title>
        <description>&lt;p&gt;The Strong Parameters &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#permit&lt;/code&gt; method only allows permitted &lt;em&gt;scalar&lt;/em&gt; values by default. See &lt;a href=&quot;https://github.com/rails/strong_parameters#permitted-scalar-values&quot;&gt;the documentation on permitted scalar values&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the important bit that I always forget:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;To declare that the value in params must be an array of permitted scalar values map the key to an empty array:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;params.permit(:id =&amp;gt; [])&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 12 Feb 2016 05:35:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2016/02/12/strong-params-permit-array.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2016/02/12/strong-params-permit-array.html</guid>
      </item>
    
      <item>
        <title>Postman and Authorization Bearer tokens</title>
        <description>&lt;p&gt;The Jawbone API (among others) uses an &lt;a href=&quot;https://developers.google.com/gmail/markup/actions/verifying-bearer-tokens&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization Bearer&lt;/code&gt; token&lt;/a&gt; in the header to &lt;a href=&quot;https://jawbone.com/up/developer/authentication&quot;&gt;specify the user’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;access_token&lt;/code&gt; &lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So if you’re using &lt;a href=&quot;https://www.getpostman.com/&quot;&gt;Postman&lt;/a&gt; to debug your API access, how do you use the Postman UI &lt;em&gt;specify&lt;/em&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bearer token&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization&lt;/code&gt; header?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Click the Headers button&lt;/li&gt;
  &lt;li&gt;Set a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Header&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Value&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bearer USERSACCESSTOKENGOESHERE &lt;/code&gt; .  That is,
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bearer&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;followed by a space&lt;/li&gt;
      &lt;li&gt;followed by the user’s access token&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a screencap of Postman in action:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.bobgilmore.name/img/postman_authorization_bearer_screencap.png&quot; alt=&quot;Postman with Authorization Bearer in the header&quot; /&gt;&lt;/p&gt;

</description>
        <pubDate>Fri, 12 Jun 2015 09:30:00 -0400</pubDate>
        <link>http://blog.bobgilmore.name/2015/06/12/postman-auth-bearer-header.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2015/06/12/postman-auth-bearer-header.html</guid>
      </item>
    
      <item>
        <title>Swift @autoclosure and Lazy Evaluation</title>
        <description>&lt;p&gt;Wow, this is a bit late to the party, but I just read about Swift’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@autoclosure&lt;/code&gt; attribute on &lt;a href=&quot;https://developer.apple.com/swift/blog/?id=4&quot;&gt;Apple’s Swift blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s mentioned in the context of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assert&lt;/code&gt; functions, but using it to allow &lt;em&gt;users&lt;/em&gt; to create lazy-evaluation functions, &lt;em&gt;a la&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;?  Mind. Blown.&lt;/p&gt;

&lt;p&gt;Also, the description caused a subtle shift in my understanding of closures, in the context of “lazy evaluation.”  Gonna have to sleep on that!&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Feb 2015 11:00:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2015/02/12/swift-lazy-evaluation.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2015/02/12/swift-lazy-evaluation.html</guid>
      </item>
    
      <item>
        <title>It's a Markdown Christmas</title>
        <description>&lt;p&gt;We finished our Christmas letter to friends and family. As web nerd-ily as possible, of course. I…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Wrote a draft in &lt;a href=&quot;http://daringfireball.net/projects/markdown/syntax&quot;&gt;Markdown&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Edited it with the wife via email.  She doesn’t have a Markdown editor, or even a reader, but who cares?  It’s plain text. That’s the &lt;em&gt;point&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;When we finished editing I checked it into a new git repo.  Because who doesn’t?&lt;/li&gt;
  &lt;li&gt;Then I dove into the CSS. Because I’m a web developer.
    &lt;ul&gt;
      &lt;li&gt;Got the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;margin&lt;/code&gt; right for our Christmas stationary.&lt;/li&gt;
      &lt;li&gt;Chose a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;font-family&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;font-size&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Ran it through &lt;a href=&quot;http://marked2app.com/&quot;&gt;Marked&lt;/a&gt; to print.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hooray for another Microsoft Word-free (&lt;em&gt;and&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;troff&lt;/code&gt;-free) Christmas!&lt;/p&gt;

&lt;p&gt;The Christmas letter repo will eventually appear &lt;a href=&quot;https://github.com/bobgilmore/christmas_letters&quot;&gt;on GitHub&lt;/a&gt;.  Not yet, though - I want to mail them first!&lt;/p&gt;
</description>
        <pubDate>Wed, 17 Dec 2014 03:00:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2014/12/17/markdown-christmas.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2014/12/17/markdown-christmas.html</guid>
      </item>
    
      <item>
        <title>FactoryGirl and after_initalize</title>
        <description>&lt;p&gt;I use &lt;a href=&quot;https://github.com/thoughtbot/factory_girl&quot;&gt;FactoryGirl&lt;/a&gt; for testing, and found a major problem &lt;em&gt;and&lt;/em&gt; solution last week.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;We use Rails &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;after_initialization&lt;/code&gt; &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html&quot;&gt;callbacks&lt;/a&gt; in object construction, but Rails was acting as if the parameters that we passed to FactoryGirl &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;create&lt;/code&gt; calls weren’t there.&lt;/p&gt;

&lt;p&gt;Well, they weren’t, at least not at object initialization..&lt;/p&gt;

&lt;h2 id=&quot;whats-going-on&quot;&gt;What’s Going On&lt;/h2&gt;
&lt;p&gt;Turns out that FactoryGirl’s default behavior is to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;create&lt;/code&gt; the object with &lt;em&gt;no&lt;/em&gt; arguments, and then set the properties &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;after&lt;/code&gt; object initialization.  Hey, guess what?  That’s too late for use in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;after_initialization&lt;/code&gt; callbacks.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;You can &lt;a href=&quot;https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#custom-construction&quot;&gt;customize a Factory’s constructor&lt;/a&gt; to pass certain (or all) parameters to a particular factory.  I had the best luck using the big hammer of&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;initialize_with { new(attributes) }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Your results may vary.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;https://twitter.com/typed&quot;&gt;@typed&lt;/a&gt; for pointing this out!&lt;/p&gt;
</description>
        <pubDate>Fri, 05 Dec 2014 03:00:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2014/12/05/factorygirl-after_initialize.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2014/12/05/factorygirl-after_initialize.html</guid>
      </item>
    
      <item>
        <title>An Auto-Expanding CDPATH</title>
        <description>&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$CDPATH&lt;/code&gt; is a great tool on Unix (including Mac).  It’s an environment variable that improves &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt;, by letting you go to certain “far-away” directories without typing the whole path to get there.&lt;/p&gt;

&lt;p&gt;There’s a good, succinct &lt;a href=&quot;http://bocoup.com/weblog/shell-hacking-cdpath/&quot;&gt;description from our neighbors at Bocoup&lt;/a&gt;.  It also mentions using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash-completion&lt;/code&gt; to make it even more useful.  Check out the &lt;a href=&quot;http://pivotallabs.com/cdpath-bash-completion-in-osx/&quot;&gt;Pivotal Labs blog&lt;/a&gt; for details.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$CDPATH&lt;/code&gt; is good on its own, but not &lt;em&gt;great&lt;/em&gt;.  To use it, you have to hard-code the &lt;em&gt;parents&lt;/em&gt; of the directories that you want easy access to (yeesh!) into one of your bash (or zsh) dotfiles.  That’s a pain, especially since I share dotfiles across machines.&lt;/p&gt;

&lt;p&gt;But wait… standardization to the rescue!&lt;/p&gt;

&lt;p&gt;Remember &lt;a href=&quot;http://blog.bobgilmore.name/2014/12/01/organizing-code.html&quot;&gt;last time&lt;/a&gt;, when I mentioned that I keep my code projects in a predictable hierarchy?  They’re all of the form &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$HOME/code/organization_name/project_name&lt;/code&gt;.  So, I put this in my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Add all code repos (if they exist) to the end of CDPATH
if [ -d &quot;$HOME/code&quot; ]; then
    export CDPATH=&quot;.:$(find $HOME/code -type d -depth 1 -maxdepth 1 | tr &apos;\n&apos; &apos;:&apos;)&quot;
fi
# Initialize bash_completion if it&apos;s available
if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export CDPATH&lt;/code&gt; line expands out to include &lt;em&gt;all&lt;/em&gt; of the directories one level deep in $HOME/code. Since &lt;em&gt;those&lt;/em&gt; directories include all of my coding projects, well, now they’re all just one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; away.  Between that and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash_completion&lt;/code&gt;, command line navigation just got super-easy!&lt;/p&gt;
</description>
        <pubDate>Wed, 03 Dec 2014 03:00:00 -0500</pubDate>
        <link>http://blog.bobgilmore.name/2014/12/03/cdpath-expansion.html</link>
        <guid isPermaLink="true">http://blog.bobgilmore.name/2014/12/03/cdpath-expansion.html</guid>
      </item>
    
  </channel>
</rss>