<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Jimmy Schementi</title>
		<description>Jimmy Schementi's website</description>
		<link>http://jimmy.schementi.com</link>
		<atom:link href="http://jimmy.schementi.com/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Get Your Infrastructure Right</title>
				<description>&lt;style&gt;
  .post {
    position: relative;
    /*font-weight: 300;
    font-family: &quot;Helvetica Neue&quot;, Helvetica, sans-serif;*/
  }
  .brooklynjs-box {
    border: 4px solid #222;
    background: #222;
    color: #fff;
  }
  .brooklynjs-box-caption {
    width: 500px;
    margin: 0px auto;
    margin-top: 2em;
  }
  .brooklynjs-box p {
    color: #eee;
    font-size: 17px;
    line-height: 1.5em;
  }
  .brooklynjs-box a {
    color: #fff;
    text-decoration: none;
    font-weight: bold;
  }
  .brooklynjs-box a:hover {
    text-decoration: underline;
  }
  .brooklynjs-logo-box {
    font-size: 20px;
    font-weight: 300;
    font-family: &quot;Helvetica Neue&quot;, Helvetica, sans-serif;
    letter-spacing: .015em;
  }
  .brooklynjs-logo {
    width: 500px;
    margin: 20px auto;
    font-weight: bold;
    font-size: 72px;
    text-align: left;
    border-top: 4px solid #fff;
    line-height: 68px;
    position: relative;
  }
  .brooklynjs-logo .j {
    right: 80px;
  }
  .brooklynjs-logo .s {
    right: 0;
  }
  .brooklynjs-logo span {
    position: absolute;
    top: 7px;
    height: 72px;
    width: 72px;
    border-radius: 50%;
    line-height: 72px;
    font-size: 60px;
    text-align: center;
    background: #f7df1e;
    color: #222;
  }
  img[title=&quot;Heroku&quot;],
  img[title=&quot;Docker&quot;],
  img[title=&quot;Amazon Web Services&quot;],
  img[title=&quot;Digital Ocean&quot;] {
    margin-bottom: -15px;
    margin-top: 15px;
  }
  img[title=&quot;Heroku&quot;] {
    height: 5em;
  }
  img[title=&quot;Docker&quot;],
  img[title=&quot;Amazon Web Services&quot;]{
    height: 7em;
  }
  img[title=&quot;Digital Ocean&quot;] {
    height: 8em;
  }
  span.center {
    display: block;
    text-align: center;
    padding: 1em;
  }
  a[title=&quot;Fuck you!&quot;] {
    color: inherit;
    text-decoration: inherit;
  }
  a[title=&quot;Fuck you!&quot;]:hover {
    color: inherit;
    text-decoration: underline;
  }
&lt;/style&gt;

&lt;style&gt;
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
.slide-style article,.slide-style aside,.slide-style details,.slide-style figcaption,.slide-style figure,.slide-style footer,.slide-style header,.slide-style hgroup,.slide-style main,.slide-style nav,.slide-style section,.slide-style summary{display:block}
.slide-style audio,.slide-style canvas,.slide-style progress,.slide-style video{display:inline-block;vertical-align:baseline}
.slide-style audio:not([controls]){display:none;height:0}
.slide-style [hidden],.slide-style template{display:none}
.slide-style a{background:0 0}
.slide-style a:active,.slide-style a:hover{outline:0}
.slide-style abbr[title]{border-bottom:1px dotted}
.slide-style b{font-weight:700}
.slide-style dfn{font-style:italic}
.slide-style h1{font-size:2em}
.slide-style mark{background:#ff0;color:#000}
.slide-style small{font-size:80%}sub,.slide-style sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.slide-style sup{top:-.5em}.slide-style sub{bottom:-.25em}.slide-style img{border:0}
.slide-style svg:not(:root){overflow:hidden}
.slide-style figure{margin:1em 40px}
.slide-style hr{box-sizing:content-box}
.slide-style pre{overflow:auto}
.slide-style code,.slide-style kbd,.slide-style pre,.slide-style samp{font-size:1em}
.slide-style kbd,.slide-style pre,.slide-style samp{font-family:monospace, monospace}
.slide-style button,.slide-style input,.slide-style optgroup,.slide-style select,.slide-style textarea{color:inherit;font:inherit;margin:0}
.slide-style button{overflow:visible}
.slide-style button,.slide-style select{text-transform:none}
.slide-style button,.slide-style input[type=&quot;button&quot;],.slide-style input[type=&quot;reset&quot;],.slide-style input[type=&quot;submit&quot;]{-webkit-appearance:button;cursor:pointer}
.slide-style button[disabled],.slide-style input[disabled]{cursor:default}
.slide-style button::-moz-focus-inner,.slide-style input::-moz-focus-inner{border:0;padding:0}
.slide-style input{line-height:normal}
.slide-style input[type=&quot;checkbox&quot;],.slide-style input[type=&quot;radio&quot;]{box-sizing:border-box;padding:0}
.slide-style input[type=&quot;number&quot;]::-webkit-inner-spin-button,.slide-style input[type=&quot;number&quot;]::-webkit-outer-spin-button{height:auto}
.slide-style input[type=&quot;search&quot;]{-webkit-appearance:textfield;box-sizing:content-box}
.slide-style input[type=&quot;search&quot;]::-webkit-search-cancel-button,.slide-style input[type=&quot;search&quot;]::-webkit-search-decoration{-webkit-appearance:none}
.slide-style fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
.slide-style legend{border:0;padding:0}
.slide-style textarea{overflow:auto}
.slide-style optgroup{font-weight:700}
.slide-style table{border-collapse:collapse;border-spacing:0}
.slide-style td,.slide-style th,.slide-style *{padding:0}
.slide-style *{margin:0}
.slide-style .bespoke-parent{font-size:1.5em;background:#111;color:#ddd;font-family:futura, helvetica, arial, arial, sans-serif;overflow:hidden;text-align:center;-webkit-transition:background 1s ease;transition:background 1s ease;background-position:50% 50%}
/*.slide-style .bespoke-parent,.slide-style .bespoke-scale-parent{position:absolute;top:0;left:0;right:0;bottom:0}*/
.slide-style .bespoke-parent,.slide-style .bespoke-scale-parent{position:relative}
.slide-style .bespoke-parent h2, .slide-style .bespoke-parent h3  { color: #ddd; }
.slide-style .bespoke-scale-parent{pointer-events:none;z-index:1}
.slide-style .bespoke-scale-parent .bespoke-active{pointer-events:auto}
.slide-style .bespoke-slide{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;/*width:940px;height:480px;position:absolute;top:50%;left:50%;margin-left:-470px;margin-top:-240px;*/display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;z-index:1}
.slide-style .bespoke-active{-webkit-transition-delay:.5s;transition-delay:.5s}
.slide-style .bespoke-active[data-bespoke-backdrop]{-webkit-transition-delay:.75s;transition-delay:.75s}
.slide-style .bespoke-inactive{opacity:0;pointer-events:none}
.slide-style .bespoke-backdrop{-webkit-transition:opacity 1s ease;position:absolute;top:0;left:0;right:0;bottom:0}
.slide-style .bespoke-progress-parent{position:absolute;top:0;left:0;right:0;height:.3vw;z-index:1}
.slide-style .bespoke-progress-bar{background:#ddd;position:absolute;top:0;left:0;height:100%;-webkit-transition:width 1s ease;transition:width 1s ease}
.slide-style .bespoke-bullet{-webkit-transition:opacity .3s ease;transition:opacity .3s ease}
.slide-style .bespoke-bullet-inactive{opacity:0}
.slide-style strong{font-weight:400}
.slide-style hr{width:50%;margin:1rem auto;height:1px;border:0;background:#ddd}
.slide-style h3,.slide-style p,.slide-style li{padding-left:20px;padding-right:20px}
.slide-style h3,.slide-style h4,.slide-style p,.slide-style li,.slide-style pre{font-weight:200}
.slide-style h1{line-height:1.4em;padding:1em;border:1px solid #ddd;border-left-width:0;border-right-width:0;min-width:8em}
.slide-style h1,.slide-style h2{letter-spacing:.3em;text-transform:uppercase;font-weight:400;margin:.17em 0;position:relative}
.slide-style h2{line-height:1.1em;padding:0 0 0 .3em}
.slide-style h3{font-family:didot, times new roman, serif;font-style:italic;font-size:1.2em;line-height:1.6em;margin:.5em 0}
.slide-style h4{text-transform:uppercase;font-size:.8em;line-height:1.8em;letter-spacing:.3em;margin:1em 0}
.slide-style ul,.slide-style ol{padding:0;margin:0;text-align:left}
.slide-style li{list-style:none;margin:.2em;font-style:normal;-webkit-transform:translateX(-6px);-ms-transform:translateX(-6px);transform:translateX(-6px)}
.slide-style li:before{content:&apos;\2014&apos;;margin-right:4px}
.slide-style pre{background:none!important}
.slide-style code{font-family:prestige elite std, consolas, courier new, monospace!important;font-style:normal;font-weight:200!important;text-align:left}
.slide-style a{padding-left:.3em;color:currentColor;text-decoration:none;border-bottom:1px solid currentColor}
.slide-style .emphatic{background:rgb(255, 51, 0);}
.slide-style .single-words{word-spacing:9999px;line-height:2.9em;overflow:hidden}
.slide-style .bespoke-backdrop{opacity:0;-webkit-transition:opacity 1s ease,.slide-style -webkit-transform 6s ease;transition:opacity 1s ease,.slide-style transform 6s ease;background-size:cover;background-position:50% 50%;-webkit-transform:translateZ(0)scale(1.3);transform:translateZ(0)scale(1.3)}
.slide-style .bespoke-backdrop-active,.slide-style .bespoke-backdrop-before{-webkit-transform:translateZ(0);transform:translateZ(0)}
.slide-style .bespoke-backdrop-before{-webkit-transition-delay:.2s;transition-delay:.2s}
.slide-style .bespoke-backdrop-active{opacity:.5}
&lt;/style&gt;

&lt;style&gt;
.slide-style code[class*=&quot;language-&quot;],.slide-style pre[class*=&quot;language-&quot;] {
    color: #f8f8f2;
    text-shadow: 0 1px rgba(0,0,0,.3);
    font-family: Consolas,Monaco,&apos;Andale Mono&apos;,monospace;
    direction: ltr;
    text-align: left;
    white-space: pre;
    word-spacing: normal;
    word-break: normal;
    line-height: 1.5;
    -moz-tab-size: 4;
    tab-size: 4;
    -webkit-hyphens: none;
    -moz-hyphens: none;
    -ms-hyphens: none;
    hyphens: none
}
.slide-style pre[class*=&quot;language-&quot;] {
    padding: 1em;
    margin: .5em 0;
    overflow: auto;
    border-radius: .3em
}

.slide-style :not(pre)&gt;code[class*=&quot;language-&quot;],.slide-style pre[class*=&quot;language-&quot;] {
    background: #272822
}

.slide-style :not(pre)&gt;code[class*=&quot;language-&quot;] {
    padding: .1em;
    border-radius: .3em
}

.slide-style .token.comment,.slide-style .token.prolog,.slide-style .token.doctype,.slide-style .token.cdata {
    color: slategray
}

.slide-style .token.punctuation {
    color: #f8f8f2
}

.slide-style .namespace {
    opacity: .7
}

.slide-style .token.property,.slide-style .token.tag,.slide-style .token.constant,.slide-style .token.symbol,.slide-style .token.deleted {
    color: #f92672
}

.slide-style .token.boolean,.slide-style .token.number {
    color: #ae81ff
}

.slide-style .token.selector,.slide-style .token.attr-name,.slide-style .token.string,.slide-style .token.char,.slide-style .token.builtin,.slide-style .token.inserted {
    color: #a6e22e
}

.slide-style .token.operator,.slide-style .token.entity,.slide-style .token.url,.slide-style .language-css .token.string,.slide-style .style .token.string,.slide-style .token.variable {
    color: #f8f8f2
}

.slide-style .token.atrule,.slide-style .token.attr-value {
    color: #e6db74
}

.slide-style .token.keyword {
    color: #66d9ef
}

.slide-style .token.regex {
    color: #fd971f
}

.slide-style .token.important {
    color: #fd971f;
    font-weight: 700
}

.slide-style .token.entity {
    cursor: help
}

.slide-style .bespoke-parent {
  position: relative;
}

.riker-grin{background-image:url(../images/get-infrastructure-right/riker-grin.jpg);background-position-y:12% !important}
.picard-wtf{background-image:url(../images/get-infrastructure-right/picard-wtf.jpg)}
.riker-grin,.picard-wtf{opacity:.75 !important}
.slide-style .picard-wtf-slide,.slide-style .riker-grin-slide{height:16em;padding:1em}

.slide-style .light-bg {
    background-color: #fff;
}

.slide-style .light-bg,.slide-style .light-bg code[class*=&quot;language-&quot;],.slide-style .light-bg pre[class*=&quot;language-&quot;] {
    color: #333!important;
}

.slide-style .light-bg code[class*=&quot;language-&quot;] .token.operator,.slide-style .light-bg pre[class*=&quot;language-&quot;] .token.operator,.slide-style .light-bg code[class*=&quot;language-&quot;] .token.punctuation,.slide-style .light-bg pre[class*=&quot;language-&quot;] .token.punctuation {
    color: #555!important
}

.slide-style .light-bg.bespoke-backdrop-active {
    opacity: 1;
}

.slide-style .pin {
    position: absolute;
    left: 0;
    right: 0;
}

.slide-style .pin.top {
    top: 10%;
}

.slide-style .pin.bottom {
    bottom: 10%;
}

.slide-style .italic {
    font-style: italic;
    text-transform: none;
    font-family: didot, times new roman, serif
}

.slide-style .tiny-code code[class*=&quot;language-&quot;],.slide-style .tiny-code pre[class*=&quot;language-&quot;] {
    font-size: .8em;
    line-height: 1
}

.slide-style .bespoke-slide {
  padding: 1em;
  zoom: .9;
  position: relative;
}

.slide-style h1 {font-size:2em}
.slide-style h2 {font-size:1.5em;}
.slide-style h3 {font-size:1.2em;}

.post .slide-style pre {
  border: 0;
}
.post .slide-style pre code {
  border: 0;
  background-color: transparent;
  padding: 0;
}
#slides {
  display: none;
  opacity: 0;
  transition: opacity 1s;
  transition-timing-function: ease-out;
}
#slides.open {
  display: block;
}
#slides.visible {
  opacity: 1;
}
#slides iframe {
  width: 100%;
  height: 350px;
  border: 0;
}
a#open-slides .caret {
  display: inline-block;
  -webkit-transition: -webkit-transform 0.5s;
  transition: transform 0.5s;
  -webkit-transform:rotate(0deg) translateY(0);
  transform:rotate(0deg) translateY(0);
}
a#open-slides.pressed .caret {
  -webkit-transform:rotate(180deg) translateY(-3px);
  transform:rotate(180deg) translateY(-3px);
}
&lt;/style&gt;

&lt;div class=&quot;brooklynjs-box&quot;&gt;
  &lt;div class=&quot;brooklynjs-logo-box&quot;&gt;
    &lt;div class=&quot;brooklynjs-logo&quot;&gt;
      Brooklyn
      &lt;span class=&quot;j&quot;&gt;J&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;S&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;brooklynjs-box-caption&quot;&gt;
    &lt;p&gt;This is a write-up of &lt;a href=&quot;https://twitter.com/brooklyn_js/status/545755653160308738&quot;&gt;a talk&lt;/a&gt; &lt;a href=&quot;https://twitter.com/RobbieTheGeek/status/545755219154731008&quot;&gt;I gave&lt;/a&gt; at &lt;a href=&quot;http://brooklynjs.com/&quot;&gt;BrooklynJS&lt;/a&gt; on 12/18/2014,
    &lt;br /&gt;titled &lt;a href=&quot;http://jimmy.schementi.com/brooklynjs-20141218/&quot;&gt;“Build apps, not infrastructure”&lt;/a&gt;.&lt;/p&gt;
    &lt;p&gt;Follow along with &lt;a id=&quot;open-slides&quot; href=&quot;javascript:void(0)&quot;&gt;the slides &lt;span class=&quot;caret&quot;&gt;&amp;blacktriangledown;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div id=&quot;slides&quot;&gt;
    &lt;iframe src=&quot;http://jimmy.schementi.com/brooklynjs-20141218/&quot;&gt;&lt;/iframe&gt;
    &lt;p style=&quot;margin: 0; font-size: .75em; text-align: center;&quot;&gt;Use arrow keys or swipe to control slides | &lt;a href=&quot;http://jimmy.schementi.com/brooklynjs-20141218/&quot; target=&quot;_blank&quot;&gt;Open slides in a new window&lt;/a&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
  var openSlidesLink = document.querySelector(&apos;#open-slides&apos;);
  var slides = document.querySelector(&apos;#slides&apos;);
  openSlidesLink.addEventListener(&apos;click&apos;, function () {
    slides.classList.toggle(&apos;open&apos;);
    setTimeout(function () {
      slides.classList.toggle(&apos;visible&apos;);
    }, 20);
    openSlidesLink.classList.toggle(&apos;pressed&apos;);
    document.querySelector(&apos;#slides iframe&apos;).focus();
  }, false);
&lt;/script&gt;

&lt;p&gt;While most of us love building apps, we’d also love it if people
used them, and if we’re lucky, &lt;strong&gt;lots of people&lt;/strong&gt;. Problem is, then we really need
to care about how our app runs and scales, and it’s best to get it figured
out before that moment of fame arrives. Let’s look at a few of the tools and
services that you can use to manage your infrastructure, so you can spend more
time building your apps, and less dealing with keeping your app running.&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot;&gt;
      &lt;h3 class=&quot;bullet bespoke-bullet bespoke-bullet-active bespoke-bullet-current&quot;&gt;Have you ever...&lt;/h3&gt;
      &lt;div&gt;
        &lt;h2&gt;Changed code&lt;/h2&gt;
        &lt;h3&gt;directly in&lt;/h3&gt;
        &lt;h2&gt;production?&lt;/h2&gt;
      &lt;/div&gt;
      &lt;br /&gt;
    &lt;/section&gt;
    &lt;div class=&quot;emphatic bespoke-backdrop bespoke-backdrop-active&quot;&gt;&lt;/div&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;Yes, we all have changed code directly in production &lt;em&gt;(and you’re
lying if you say you haven’t)&lt;/em&gt;. We do this &lt;strong&gt;despite&lt;/strong&gt; knowning that
it’s horrible:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How many times have you found someone changed production directly
and &lt;strong&gt;forgot to check it in&lt;/strong&gt;?&lt;/li&gt;
  &lt;li&gt;Or made &lt;em&gt;[what you thought was]&lt;/em&gt; a simple code change to fix a specific
problem, but instead it revealed further problems.&lt;/li&gt;
  &lt;li&gt;Or users seeing intermittent brokenness while you make changes.&lt;/li&gt;
  &lt;li&gt;Or how do you know it works if you haven’t written tests for it?&lt;/li&gt;
  &lt;li&gt;Or! OR!&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Heck, a company even has the person editing code in production &lt;a href=&quot;http://www.bnj.com/blog/cowboy-coding-pink-sombrero/&quot; title=&quot;Cowboy Coding&quot;&gt;don a
pink sombrero&lt;/a&gt; to bring awareness to “Cowboy Coding”:&lt;/p&gt;

  &lt;p&gt;&lt;img src=&quot;/images/get-infrastructure-right/cowboy-coding.jpg&quot; alt=&quot;Cowboy coding&quot; title=&quot;Cowboy Coding&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our reasons for making changes directly in production are usually good.
&lt;em&gt;Sometimes they’re not.&lt;/em&gt; Regardless, we need to do this because our &lt;strong&gt;deployment
processes aren’t automated enough to &lt;em&gt;safely&lt;/em&gt; do this&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;
&lt;img src=&quot;/images/get-infrastructure-right/automate-all-the-things.png&quot; alt=&quot;Automate all the things&quot; title=&quot;Automate All The Things&quot; /&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Think about it - if we could quickly write a fix in a clone of production, test
it, and push it to production in seconds, wouldn’t we do that instead?&lt;/p&gt;

&lt;p&gt;It’s a lot of work to fully automate deployments, so most people have a fairly
&lt;strong&gt;manual deployment process&lt;/strong&gt;. Which is crazy, considering we’re programmers - &lt;strong&gt;all
we do is automate.&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot;&gt;
      &lt;h2 class=&quot;bullet bespoke-bullet bespoke-bullet-active&quot;&gt;&lt;span&gt;Application&lt;/span&gt;&lt;span class=&quot;bullet italic bespoke-bullet bespoke-bullet-active&quot;&gt;&amp;nbsp;(feature)&lt;/span&gt;&lt;/h2&gt;
      &lt;h3&gt;vs.&lt;/h3&gt;
      &lt;h2&gt;&lt;span&gt;Infrastructure&lt;/span&gt;&lt;span class=&quot;bullet italic bespoke-bullet bespoke-bullet-active bespoke-bullet-current&quot;&gt;&amp;nbsp;(chore)&lt;/span&gt;&lt;/h2&gt;
    &lt;/section&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;This happens mainly because &lt;strong&gt;we prioritize features&lt;/strong&gt;, or
enhancements to our applications, &lt;strong&gt;over chores&lt;/strong&gt;, which can be enhancements to our
infrastructure. This distinction comes from &lt;a href=&quot;http://en.wikipedia.org/wiki/Scrum_%28software_development%29&quot;&gt;Scrum&lt;/a&gt;, where you’re rewarded
for completing features, as those “add business value”…&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;&lt;img src=&quot;/images/get-infrastructure-right/bullshit.jpg&quot; alt=&quot;What if I told you that&apos;s bullshit&quot; title=&quot;What if I told you... that&apos;s bullshit&quot; /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete and utter bullshit…&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot;&gt;
      &lt;h2&gt;Prioritizing&lt;/h2&gt;
      &lt;h2&gt;infrastructure&lt;/h2&gt;
      &lt;h3&gt;makes it easier to&lt;/h3&gt;
      &lt;h2&gt;ship features&lt;/h2&gt;
    &lt;/section&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;A better infrastructure makes it easier to ship features.&lt;/strong&gt; A shitty/non-existant
infrastructure makes adding features exponentially harder as the system gets more
complicated. Therefore, &lt;strong&gt;infrastructure improvements are really just features as
well&lt;/strong&gt; - as they do provide end-user value, &lt;em&gt;eventually&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, most people would consider “User Signup” to be a feature, as a user interacts with
it directly. Though, at the same time, it’s more part of your infrastructure,
as it’s not the product itself, but &lt;em&gt;a necessary evil to use the product&lt;/em&gt;. But,
you’d never make signup be a manual process, &lt;a href=&quot;http://moven.com&quot; title=&quot;Fuck you!&quot;&gt;as that would mean no one would
sign up and you’d have no users&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;&lt;img src=&quot;/images/get-infrastructure-right/bad-time.jpg&quot; alt=&quot;If you manually do anything, you&apos;ll have a bad time&quot; title=&quot;If you manually do anything, you&apos;re going to have a bad time.&quot; /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Same should go for
deployments - if it’s not automatic, you’ll be &lt;strong&gt;afraid of deploying&lt;/strong&gt;, and
favor large deployments, which will &lt;strong&gt;create more bugs&lt;/strong&gt;, and a slew of other
anti-patterns will become part of your process. &lt;strong&gt;To build a great product, you
need to have an equally great infrastructure&lt;/strong&gt;. Your users will feel the pain when
your infrastructure doesn’t support your ability to enhance your product.&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot;&gt;
      &lt;h3&gt;Think of&lt;/h3&gt;
      &lt;h2&gt;infrastructure&lt;/h2&gt;
      &lt;h3&gt;as a&lt;/h3&gt;
      &lt;h2&gt;product&lt;/h2&gt;
      &lt;h3&gt;you provide to&lt;/h3&gt;
      &lt;h2&gt;yourself&lt;/h2&gt;
      &lt;br /&gt;
    &lt;/section&gt;
    &lt;div class=&quot;emphatic bespoke-backdrop bespoke-backdrop-active&quot;&gt;&lt;/div&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Whoa, far out man…&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, what would we want this infrastructure-as-a-product to do for us?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Runs the &lt;a href=&quot;http://12factor.net&quot; title=&quot;Twelve-Factor App&quot;&gt;Twelve-Factor App&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;This methology of building web applications and services leads to more
 maintainable and scalable products. We’ll want our infrastructure to run
 these apps, as these are the apps we’ll write. &lt;a href=&quot;http://12factor.net&quot; title=&quot;Twelve-Factor App&quot;&gt;Read more about 12-factor
 apps&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Deploy a new app&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;New apps should be able to be deployed to any environment &lt;em&gt;within minutes&lt;/em&gt;.
 Given that we prefer &lt;a href=&quot;http://martinfowler.com/articles/microservices.html&quot;&gt;micro-services&lt;/a&gt; over more monolithic architectures,
 this is an important feature - new server provisioning will happen very
 often. Infrastructures which requires significant effort to provision new
 servers tend to avoid this patter, leading to an application which is &lt;strong&gt;harder
 to scale and evolve&lt;/strong&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Automated scaling&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Every web app or service should be behind its own load-balancer, which you
 can easily add or remove individual servers to. The creation of these
 servers should be fully-automated to allow the load-balancer to create more
 instance for you.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Deploying should not introduce downtime&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Deploying an existing app or service shouldn’t make itself unavailable during
 deployment. It should also allow for rollback, in case a new deployment isn’t
 functioning properly, and versioning, to run multiple versions of the same
 app.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Create and clone environments&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Environments, a collection of all servers and configuration, should be
 easily created or cloned. This environment can be anywhere - in the cloud,
 or locally to develop against.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Everything is automated&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Minimal manual processes should be involving in doing any of the above
 features. Any modifications made to a default environment should be
 repeatable.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sounds awesome, right? Does it already exist? Does it &lt;em&gt;kind of&lt;/em&gt; already exist?
Let’s see what tools and services already exist that could help us out:&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;
&lt;img src=&quot;/images/get-infrastructure-right/heroku-logo.jpg&quot; alt=&quot;Heroku&quot; title=&quot;Heroku&quot; /&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt; is “the” platform-as-a-service. It popularized many of the
&lt;a href=&quot;http://12factor.net&quot; title=&quot;Twelve-Factor App&quot;&gt;12-factor app&lt;/a&gt; practices. It was the first to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt; to trigger deployments.
Most importantly, it provides developers with a clean abstraction of an app,
hiding the complexities how to run the app. While &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;’s featureset is almost
exactly what we want, this abstraction comes at a price - quite literally.
Heroku is fairly expensive ($34.50/month for the low-end 2-server setup). It becomes more
expensive as you use add-ons (for example, $50/month for low-end Postgres).
Also, using Heroku is much more difficult (and expensive) to use for a utility
server, like Jenkins or Graphite, which may have higher CPU requirements
(nothing worse than slow builds).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That’s not to say if you’re using Heroku you shouldn’t, it’s a great service.
Just be aware of the pros and cons.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Though, how Heroku deploys applications is very interesting. Heroku has a
concept of a &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;buildpack&lt;/a&gt;, which contains the logic to detect a specific type of
application and deploy it. &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;Heroku Buildpacks&lt;/a&gt; are all open-source,
meaning you can write your own, allowing Heroku to run almost anything. We can
also use &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;Heroku Buildpacks&lt;/a&gt; to provision our own servers…&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;
&lt;img src=&quot;/images/get-infrastructure-right/docker.png&quot; alt=&quot;Docker&quot; title=&quot;Docker&quot; /&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; provides application containers, which provides the applications with an
isolated view of the operating system - their own process ID space, filesystem,
and network interfaces. It also provides contraints on system resources (memory,
CPU, network I/O).&lt;/p&gt;

&lt;p&gt;Essentially &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; can be used to provision and deploy applications, as an
alternative to &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;Heroku Buildpacks&lt;/a&gt;. The difference is &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; can
be used to run an identical environment locally as well as when deployed, and
can run other apps like databases.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;
&lt;img src=&quot;/images/get-infrastructure-right/aws.png&quot; alt=&quot;Amazon Web Services&quot; title=&quot;Amazon Web Services&quot; /&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://aws.amazon.com&quot;&gt;Amazon Web Services (AWS)&lt;/a&gt; is a &lt;strong&gt;massive&lt;/strong&gt; collection of services. &lt;strong&gt;37 different
services&lt;/strong&gt; to be exact:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/get-infrastructure-right/AWS_Management_Console.png&quot; alt=&quot;Amazon Web Services Features&quot; title=&quot;AWS Features&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the core is &lt;a href=&quot;http://aws.amazon.com/ec2/&quot; title=&quot;Amazon EC2&quot;&gt;Elastic Compute Cloud (EC2)&lt;/a&gt;, which allows you to run and manage
arbitrary &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_machine&quot;&gt;virtual machines&lt;/a&gt; in Amazon’s data centers. &lt;a href=&quot;http://aws.amazon.com/ec2/&quot; title=&quot;Amazon EC2&quot;&gt;EC2&lt;/a&gt; also has sub-services to help route network traffic
to your &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_machine&quot;&gt;VMs&lt;/a&gt;, specifically &lt;a href=&quot;http://aws.amazon.com/elasticloadbalancing/&quot;&gt;a TCP and HTTP load-balancer&lt;/a&gt;, as well as &lt;a href=&quot;http://aws.amazon.com/autoscaling/&quot;&gt;Auto Scaling&lt;/a&gt;,
which helps you launch &lt;a href=&quot;http://aws.amazon.com/ec2/instance-types/&quot;&gt;instances&lt;/a&gt; and add them to a load-balancer.&lt;/p&gt;

&lt;p&gt;Another useful service is &lt;a href=&quot;http://aws.amazon.com/s3/&quot;&gt;Simple Storage Service (S3)&lt;/a&gt;, which stores
arbitrary data like a file system. It can also serve those files over HTTP, making it an ideal
static HTTP server, as you don’t have to manage servers or load-balancers.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;35 other services&lt;/em&gt; do lots of useful things, like various data storage
services, &lt;a href=&quot;http://aws.amazon.com/vpc/&quot;&gt;private networks&lt;/a&gt;, &lt;a href=&quot;http://aws.amazon.com/route53/&quot;&gt;DNS&lt;/a&gt;, app and mobile services, deployment/provisioning stuff, oh my!
It can get very confusing for newcomers and experienced engineer alike,
as some of the services overlap in functionality. For example,
&lt;a href=&quot;http://aws.amazon.com/opsworks/&quot;&gt;OpsWorks&lt;/a&gt;, &lt;a href=&quot;http://aws.amazon.com/cloudformation/&quot;&gt;CloudFormation&lt;/a&gt;, and &lt;a href=&quot;http://aws.amazon.com/elasticbeanstalk/&quot;&gt;Beanstalk&lt;/a&gt;
all can do very similar things. Or complete with existing Open Source offerings, like
&lt;a href=&quot;http://aws.amazon.com/dynamodb/&quot;&gt;DynamoDB&lt;/a&gt; vs. &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://aws.amazon.com/elasticbeanstalk/&quot;&gt;Elastic Beanstalk&lt;/a&gt; is worth noting, because it provides a similar
feature-set to Heroku - it can deploy applications to EC2 instances, and
auto-configures auto scaling and load balancing. However, the pre-configured
environments are awkward to configure, using the special &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.elasticbeanstalk&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ebextensions&lt;/code&gt; directories, and creating a
&lt;a href=&quot;http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.customenv.html&quot;&gt;custom AMI for Elastic Beanstalk&lt;/a&gt; somewhat violates
the “infrastructure as code” tenant. Also, it’s all or nothing - so if
your application isn’t supported by &lt;a href=&quot;http://aws.amazon.com/elasticbeanstalk/&quot;&gt;Elastic Beanstalk&lt;/a&gt;, like
&lt;a href=&quot;https://golang.org/&quot;&gt;GoLang&lt;/a&gt;, you can’t use it.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Recently, Amazon improved &lt;a href=&quot;http://aws.amazon.com/elasticbeanstalk/&quot;&gt;Elastic Beanstalk&lt;/a&gt; by adding support
for &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;, which can be used to avoid all the environment weirdnesses,
standardize provisioning, and support other languages. It also supports
&lt;a href=&quot;http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.rollingupdates.html&quot;&gt;rolling updates&lt;/a&gt;, meaning there’s no downtime during a deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Amazon has recently added some new services, currently in preview, which are
promising:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/codedeploy/&quot;&gt;CodeDeploy&lt;/a&gt; manages applications and how to deploy them (some overlap with Beanstalk, but a bit more general)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/ecs/&quot;&gt;EC2 Container Service&lt;/a&gt; supports clustering of Docker containers&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/lambda/&quot;&gt;Lambda&lt;/a&gt; - respond to events with code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span class=&quot;center&quot;&gt;
&lt;img src=&quot;/images/get-infrastructure-right/docean.svg&quot; alt=&quot;Digital Ocean&quot; title=&quot;Digital Ocean&quot; /&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For those completely overwelmed by &lt;a href=&quot;http://aws.amazon.com&quot;&gt;AWS&lt;/a&gt;, or just looking for something simpler,
&lt;a href=&quot;https://www.digitalocean.com/&quot;&gt;Digital Ocean&lt;/a&gt; is basically the equivalent of &lt;a href=&quot;http://aws.amazon.com/ec2/&quot; title=&quot;Amazon EC2&quot;&gt;EC2&lt;/a&gt; and &lt;a href=&quot;http://aws.amazon.com/route53/&quot;&gt;Route53&lt;/a&gt;,
but with an awesome user interface for both the website and the &lt;a href=&quot;https://developers.digitalocean.com/&quot;&gt;API&lt;/a&gt;, making it
much easier to work with.&lt;/p&gt;

&lt;p&gt;Because it’s only for running &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server&quot;&gt;droplets&lt;/a&gt; (their word for VMs), any load
balancing needs to be done with another dedicated &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server&quot;&gt;droplet&lt;/a&gt; (eg. &lt;a href=&quot;http://www.haproxy.org/&quot;&gt;HAProxy&lt;/a&gt;),
and scaled manually.&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;div class=&quot;bespoke-parent&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot;&gt;
      &lt;h3 style=&quot;font-size: 1.5em&quot;&gt;Feels like something&apos;s missing...&lt;/h3&gt;
    &lt;/section&gt;
    &lt;div class=&quot;emphatic bespoke-backdrop bespoke-backdrop-active&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Seems like we can use all this for the major features of our infrastructure, but
nothing integrates it all together and makes it as easy as Heroku.&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent riker-grin-slide&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot; style=&quot;zoom: 0.947872340425532;&quot;&gt;
      &lt;div class=&quot;pin top&quot;&gt;
        &lt;h2&gt;Riker&lt;/h2&gt;
        &lt;h3&gt;Heroku-like application deployments for&lt;br /&gt;Amazon Web Services.&lt;/h3&gt;
      &lt;/div&gt;
    &lt;/section&gt;
    &lt;div class=&quot;riker-grin bespoke-backdrop bespoke-backdrop-active&quot;&gt;&lt;/div&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;Riker gives you Heroku-like application deployments for Amazon Web Services. It
automates all the best-practices of application deployment, so you don’t have to
piece things together.&lt;/p&gt;

&lt;p&gt;Riker deploys any application with a &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;buildpack&lt;/a&gt; to &lt;a href=&quot;http://aws.amazon.com&quot;&gt;AWS&lt;/a&gt;, and
automatically configures load balancing and auto scaling for you, as well as
manages rolling deployments. It also can deploy static websites to S3.&lt;/p&gt;

&lt;p&gt;Next I’d like to make the target “cloud” be extensible (most likely &lt;a href=&quot;https://www.digitalocean.com/&quot;&gt;Digital
Ocean&lt;/a&gt; as a first), support &lt;a href=&quot;https://docs.docker.com/reference/builder/&quot;&gt;Dockerfiles&lt;/a&gt; as an alternative
to &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;buildpacks&lt;/a&gt;, and use some of &lt;a href=&quot;http://aws.amazon.com&quot;&gt;AWS&lt;/a&gt;’s new features, like the &lt;a href=&quot;http://aws.amazon.com/ecs/&quot;&gt;EC2
Container Service&lt;/a&gt;, &lt;a href=&quot;http://aws.amazon.com/codedeploy/&quot;&gt;CodeDeploy&lt;/a&gt;, and &lt;a href=&quot;http://aws.amazon.com/lambda/&quot;&gt;Lambda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out my &lt;a href=&quot;/riker-heroku-like-app-deploy-for-aws&quot;&gt;initial post about Riker&lt;/a&gt;, as it’s the same content
I spoke about in my talk. Here’s some other useful links:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jschementi/riker&quot;&gt;Project on GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.python.org/pypi/riker&quot;&gt;Riker on Python Package Index&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jschementi/riker/issues&quot;&gt;Issues list&lt;/a&gt; &lt;em&gt;(for roadmap as well as report bugs)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jschementi/riker/pulls&quot;&gt;Pull requests&lt;/a&gt; would be much appreciated!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to &lt;em&gt;(eventually)&lt;/em&gt; spend less time managing your infrastructure, and
more time building products, or are just interested in making infrastructure
management better, give Riker a try and come help me build it!&lt;/p&gt;

&lt;div class=&quot;slide-style&quot;&gt;
  &lt;article class=&quot;bespoke-parent picard-wtf-slide&quot;&gt;
    &lt;section class=&quot;bespoke-slide bespoke-active&quot; style=&quot;zoom: 0.947872340425532;&quot;&gt;
      &lt;h3 style=&quot;padding-left: 40%;padding-top: 5%&quot;&gt;You&apos;re the captain, make Riker your #1&lt;/h3&gt;
    &lt;/section&gt;
    &lt;div class=&quot;picard-wtf bespoke-backdrop bespoke-backdrop-active&quot;&gt;&lt;/div&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Yeah, I’m a Trekky…&lt;/em&gt;&lt;/p&gt;

&lt;!--
#### Old blog post

I’d much rather focus on building a system, knowing that deployments and
scaling are already     And if I push that work off until the system is
bigger or traffic start increasing, it takes even more time. Unless I use
Heroku; then I spend very little time, but mainly because I control very
little.

As the applications we build for the web get more complex, so does deploying
and managing them. Remember when deploying your website was no more complex
than FTP-ing PHP files to your servers, and maybe running some MySQL scripts.
Your servers were either hosted by another company, or your own hardware, and
you just had one or two. You setup Apache and MySQL just once, and didn&apos;t
really have to think about your infrastructure much more than that - you spent
all your time focused on building your website.

How the times have changed. Now, we build web applications, and boy are they
more complex. The web server is usually just a forward proxy to your
application&apos;s processes, which themselves run a web server, and are written in
various programming languages. These applications do more than just generate
HTML - they also serve data which is consumed by any number of web browser and
native client applications. To accomplish this, your application&apos;s depend on
various technologies like key-value stores, message queues, and possibly
different types of relational and object databases. And all this runs on
virtual machines. All this extra complexity means a bunch more ways things can
break, so each component needs to be monitored. All this means more time
managing the infrastructure, and less time building your application.

There are no shortage of tools meant to help manage this infrastructure,
too many to name here. However, the infrastructure still gets in our way -
it&apos;s still way to hard to ship features to our users. We need to get back to
the simplicity of just publishing your code, and the &quot;infrastructure&quot; does
what&apos;s necessary to deploy it.

One service has set the standard for this - Heroku. With a few commands, you
can get your application deployed to the internet, without needing to deal with
setting up virtual machines. For most applications this is great when they
first start out, but that lack of control starts to become a burdeon as they
grow. Also, while Heroku allows you to manually scale up your applications, the cost of doing so becomes fairly high.

#### &amp;lt;/end&amp;gt; Old blog post
--&gt;

</description>
				<pubDate>Tue, 30 Dec 2014 00:00:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/get-infrastructure-right</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/get-infrastructure-right</guid>
			</item>
		
			<item>
				<title>Riker - Heroku-like app deployments for AWS</title>
				<description>&lt;p&gt;&lt;a href=&quot;https://github.com/jschementi/riker&quot; title=&quot;Riker&quot;&gt;&lt;img src=&quot;/images/riker-phaser.jpg&quot; alt=&quot;William Riker&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/jschementi/riker&quot; title=&quot;Riker&quot;&gt;Riker&lt;/a&gt; turns &lt;a href=&quot;http://aws.amazon.com/&quot; title=&quot;Amazon Web Services&quot;&gt;Amazon Web Services&lt;/a&gt; into your very own
&lt;a href=&quot;http://en.wikipedia.org/wiki/Platform_as_a_service&quot; title=&quot;Platform as a Service&quot;&gt;Platform as a Service&lt;/a&gt;, giving you the same ease-of-use that platforms like &lt;a href=&quot;http://heroku.com&quot; title=&quot;Heroku&quot;&gt;Heroku&lt;/a&gt;
provide, while retaining the control that is attractive about &lt;a href=&quot;http://aws.amazon.com/&quot; title=&quot;Amazon Web Services&quot;&gt;AWS&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h3&gt;

&lt;p&gt;Getting started with &lt;a href=&quot;https://github.com/jschementi/riker&quot; title=&quot;Riker&quot;&gt;Riker&lt;/a&gt; is easy: just install it using &lt;a href=&quot;http://pip.readthedocs.org/en/latest/installing.html#install-pip&quot; title=&quot;Python Install Python&quot;&gt;pip&lt;/a&gt; and Riker
will prompt you for the necessary information it needs:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;riker
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker config&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;deploy-a-nodejs-app&quot;&gt;Deploy a Node.js app&lt;/h3&gt;

&lt;p&gt;First, let’s clone a sample &lt;a href=&quot;http://nodejs.org/&quot; title=&quot;Node.js&quot;&gt;Node.js&lt;/a&gt; app:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone git@github.com:heroku/node-js-sample.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;node-js-sample&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then deploy it with just one command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker deploy&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And open it in your default web browser:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker open&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That’s it! While this example deploys a sample &lt;a href=&quot;http://nodejs.org/&quot; title=&quot;Node.js&quot;&gt;Node.js&lt;/a&gt; application, any
language can be deployed, since Riker uses &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot; title=&quot;Heroku Buildpacks&quot;&gt;Heroku Buildpacks&lt;/a&gt;. &lt;a href=&quot;https://github.com/jschementi/riker/issues/30&quot;&gt;More
information on exactly what buildpacks Riker supports, and how to use a custom
buildpack&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;deploy-a-static-website&quot;&gt;Deploy a static website&lt;/h3&gt;

&lt;p&gt;Riker can also be used to deploy static websites to &lt;a href=&quot;http://aws.amazon.com/s3/&quot; title=&quot;Simple Storage Service&quot;&gt;S3&lt;/a&gt;, rather than running
&lt;a href=&quot;http://nginx.org/&quot; title=&quot;NGINX&quot;&gt;nginx&lt;/a&gt; or &lt;a href=&quot;http://httpd.apache.org/&quot; title=&quot;Apache&quot;&gt;apache&lt;/a&gt; in an &lt;a href=&quot;http://aws.amazon.com/ec2/&quot; title=&quot;Elastic Compute Cloud&quot;&gt;EC2&lt;/a&gt; instance to serve static files:&lt;/p&gt;

&lt;p&gt;First, generate a static website:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;static-website &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;static-website
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello, World&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; index.html
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;touch&lt;/span&gt; .s3 &lt;span class=&quot;c&quot;&gt;# tells Riker to deploy to Amazon S3&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git init &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git add &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then use the same commands as before to deploy and open the website:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker deploy
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker open&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;scalable-zero-downtime-deployments&quot;&gt;Scalable, zero-downtime deployments&lt;/h3&gt;

&lt;p&gt;Riker provides a scalable mode (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--scale&lt;/code&gt;), where &lt;a href=&quot;http://aws.amazon.com/elasticloadbalancing/&quot; title=&quot;Elastic Load Balancing&quot;&gt;load balancing&lt;/a&gt; and
&lt;a href=&quot;http://aws.amazon.com/autoscaling/&quot; title=&quot;Auto-scaling&quot;&gt;auto-scaling&lt;/a&gt; are configured for you. This also ensures zero-downtime during
deployments.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;riker deploy &lt;span class=&quot;nt&quot;&gt;--scale&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h3&gt;

&lt;p&gt;Riker provides a set of best-practices and structure to your infrastructure,
while leaning on as much of the features AWS provides as possible.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Load Balancing: &lt;a href=&quot;http://aws.amazon.com/elasticloadbalancing/&quot; title=&quot;Elastic Load Balancing&quot;&gt;Elastic Load Balancer (ELB)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Scaling: &lt;a href=&quot;http://aws.amazon.com/autoscaling/&quot; title=&quot;Auto-scaling&quot;&gt;EC2 Auto-Scaling and Launch Configurations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;DNS: &lt;a href=&quot;http://aws.amazon.com/route53/&quot; title=&quot;Route 53&quot;&gt;Route 53&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Static website hosting: &lt;a href=&quot;http://aws.amazon.com/s3/&quot; title=&quot;Simple Storage Service&quot;&gt;Simple Storage Service (S3)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Riker doesn’t require its own server to be running; it’s just a deployment
tool (though it’s best to run Riker in a &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot; title=&quot;Continuous Integration&quot;&gt;CI&lt;/a&gt; server like &lt;a href=&quot;http://jenkins-ci.org/&quot; title=&quot;Jenkins CI&quot;&gt;Jenkins&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Riker also abstracts away the &lt;a href=&quot;http://aws.amazon.com/ec2/&quot; title=&quot;Elastic Compute Cloud&quot;&gt;EC2&lt;/a&gt; instances, and instead lets you only care
about the application itself: code, dependencies, and configuration. Riker
makes your instances easy to destroy and recreate, removing the need to ever
manually provision a machine. This also makes scaling trivial. To enable this
abstraction, Riker uses Docker to run your application in its own sandbox,
as well as &lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot; title=&quot;Heroku Buildpacks&quot;&gt;Heroku Buildpacks&lt;/a&gt; to deploy many different types of applications.
Today, Riker also uses &lt;a href=&quot;https://github.com/progrium/dokku&quot; title=&quot;Dokku&quot;&gt;Dokku&lt;/a&gt;, but may move away from it to allow Riker to also
run your application locally during development, but more about that later.&lt;/p&gt;

&lt;p&gt;By default, Riker will deploy changes directly to existing instances.
However, with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--scale&lt;/code&gt; flag, Riker will deploy changes to new instances,
and only swap old instances out for new instances when the new instances
become healthy, and the old instances no longer have active connections.&lt;/p&gt;

&lt;h3 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h3&gt;

&lt;p&gt;While Riker is in active development, it’s probably not ready for prime-time,
unless you’re really willing to help contribute and test things out.&lt;/p&gt;

&lt;h3 id=&quot;contribute&quot;&gt;Contribute&lt;/h3&gt;

&lt;p&gt;There are many ways you can help make Riker better:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Use it!&lt;/strong&gt; &lt;a href=&quot;https://github.com/jschementi/riker/issues&quot; title=&quot;Riker Issues&quot;&gt;Report bugs, suggest features and ask questions on GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Write documentation&lt;/strong&gt;: Anything you feel requires documentation, please feel
free to write it in the &lt;a href=&quot;https://github.com/jschementi/riker/wiki&quot; title=&quot;Riker Wiki&quot;&gt;Wiki&lt;/a&gt;.
&lt;a href=&quot;http://fusiongrokker.com/post/how-you-can-contribute-to-taffy-documentation&quot;&gt;Please follow these instructions for contributing to Wikis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Write code&lt;/strong&gt;: Either from the &lt;a href=&quot;https://github.com/jschementi/riker/issues&quot; title=&quot;Riker Issues&quot;&gt;Issues list&lt;/a&gt;,
or your own idea.
&lt;a href=&quot;https://github.com/jschementi/riker/pulls&quot; title=&quot;Riker Pull Requests&quot;&gt;Pull requests are encouraged!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know what you think! Look for subsequent posts about the rationale behind
Riker and why it’s different than other comparable services.&lt;/p&gt;

&lt;div style=&quot;text-align:center; font-style: italic;&quot;&gt;You’re the captain - make Riker your &quot;Number One&quot;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/jschementi/riker&quot; title=&quot;Riker&quot;&gt;&lt;img src=&quot;/images/riker-grin.jpg&quot; alt=&quot;William Riker&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
				<pubDate>Wed, 24 Sep 2014 00:00:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/riker-heroku-like-app-deploy-for-aws</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/riker-heroku-like-app-deploy-for-aws</guid>
			</item>
		
			<item>
				<title>Splitting up a Git repo</title>
				<description>&lt;p&gt;When it comes to organizing Git repositories, there’s only one way to do it:
&lt;strong&gt;a repository per project or component&lt;/strong&gt; (a web server, an iOS app, etc…).&lt;/p&gt;

&lt;p&gt;If you’ve done anything other than that, &lt;strong&gt;you’ve fucked up&lt;/strong&gt;. Maybe you have a
single repository for everything? Some combination? Sure, it might be easier to just
have one repository, but as your system grows, the ramifications of that fuck-up
become clear:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;A 1-line change to the app performs a full-redeploy of your web-server -
now you have to have your CI server only build certain jobs based on
directory’s touched. &lt;strong&gt;Yuck.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Every single server has the code for all the other servers. Now you have to
perform a build step to remove files from deployments. &lt;strong&gt;Yuck.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Large commits cutting across multiple components. Commit messages could be
considered novels. Now we have to selectively commit certain files that touch a
server, and certain files that touch the app, etc. &lt;strong&gt;Yuck.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this sounds like your project, don’t keep working around the problem - &lt;strong&gt;let’s
fix it.&lt;/strong&gt; It’s probably going to be a bit of work, but it’s necessary, so take a
deep breath, and let’s get started.&lt;/p&gt;

&lt;p&gt;The first choice you have to make is whether to preserve history or not. For
almost all cases you should preserve history, but if for some reason
you decide it’s not important, then &lt;em&gt;“these aren’t the droids you’re looking for”&lt;/em&gt;.
You just need to create new repositories, copy files to each as appropriate, and
you’re done. That might be the right choice for your project, but this isn’t
the post for you.&lt;/p&gt;

&lt;p&gt;Git gives us many tools to rewrite history, so let’s look at situations you’ll
run into, and how to use Git to deal with them.&lt;/p&gt;

&lt;h3 id=&quot;extract-a-sub-directory&quot;&gt;Extract a sub-directory&lt;/h3&gt;

&lt;p&gt;This is the best-case scenario: everything is perfect about your repository,
only you have each project/component in a sub-directory of your large repo.
For this, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git subtree split&lt;/code&gt; is exactly what you want.&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;git subtree split -prefix=subdir_to_remove -b new_project_branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;For some older versions of git, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subtree&lt;/code&gt; subcommand may be unavailable.
Instead, you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter-branch&lt;/code&gt; subcommand:&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;git filter-branch --subdirectory-filter subdir_to_remove new_project_branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then you can push each new branch to its own remote.&lt;/p&gt;

&lt;h3 id=&quot;arbitrary-paths&quot;&gt;Arbitrary paths&lt;/h3&gt;

&lt;p&gt;What if a project has two top-level directories, or shares files between projects?
Maybe a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.env&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Procfile&lt;/code&gt;?
In this case you’ll have to extract history by arbitrary paths.&lt;/p&gt;

&lt;p&gt;To do this, first we remove all non-wanted files from all git commits with the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git filter-branch&lt;/code&gt; command. Any commits that do not touch those paths will be
removed because of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--ignore-unmatch&lt;/code&gt; flag.&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;PATHS_TO_KEEP=&quot;./some_dir ./some_other_dir .env Procfile&quot;
git filter-branch -f --index-filter &quot;git rm --ignore-unmatch --cached -qr -- . &amp;amp;&amp;amp; git reset -q \$GIT_COMMIT -- $PATHS_TO_KEEP&quot; --prune-empty -- HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-- HEAD&lt;/code&gt; means to only do this transformation in the current branch.
You can replace it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-- --all&lt;/code&gt; to do it across all branches. Or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--tag-name-filter cat -- --all&lt;/code&gt; to do it across all branches AND tags. Pick your poison.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While this is great, empty merge commits are not removed by the last command!
A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parent-filter&lt;/code&gt; can be used to rewrite commit parents to remove them:&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;tmpfile=`mktemp -t splitgit`
chmod 755 $tmpfile
echo &apos;#!/usr/bin/env ruby
old_parents = gets.chomp.gsub(&quot;-p &quot;, &quot; &quot;)
new_parents = old_parents.empty? ? [] : `git show-branch --independent #{old_parents}`.split
puts new_parents.map{|p| &quot;-p &quot; + p}.join(&quot; &quot;)&apos; &amp;gt; $tmpfile
git filter-branch -f --prune-empty --parent-filter $tmpfile HEAD
rm $tmpfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;You can simplify this by writing $tmpfile to disk in a well-known location,
instead of using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mktemp&lt;/code&gt; each time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;moving-files-around&quot;&gt;Moving files around&lt;/h3&gt;

&lt;p&gt;Let’s say a new repo should still have a  file, but you want to change its
path in the new repo?  If so, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tree-filter&lt;/code&gt; can help with this. For this example,
we want to move an entire sub-directory up one level.&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;git filter-branch -f --tree-filter &apos;shopt -s dotglob nullglob; test -d sub_dir &amp;amp;&amp;amp; mv sub_dir/* . || :&apos; HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;deleting-files&quot;&gt;Deleting files&lt;/h3&gt;

&lt;p&gt;What if you just don’t want a particualr file around?&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;git filter-branch -f --index-filter &apos;git rm --cached --ignore-unmatch Rakefile&apos; --prune-empty -- HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;We use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index-filter&lt;/code&gt; here to not require files be checked out for each commit,
which makes it faster. This is different from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tree-filter&lt;/code&gt; in that it checks out
each commit’s files. This is good in that it lets you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt;, but is
slower. When formulating your own history manipulations, keep this in mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;keeping-only-certain-lines-in-a-file&quot;&gt;Keeping only certain lines in a file&lt;/h3&gt;

&lt;p&gt;(I know, this is crazy…) What if, in your old repo, you had a configuration
file that was for all projects, but now you want to only keep commits that
affected the variables for the particuar sub-project? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tree-filter&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&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;git filter-branch -f --tree-filter &apos;test -f .env &amp;amp;&amp;amp; cat .env | grep &quot;\(^VAR_X\|^VAR_Y\|^VAR_Z\)&quot; &amp;gt; .newenv &amp;amp;&amp;amp; mv .newenv .env || :&apos; --prune-empty -- HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;fucking-symlinks&quot;&gt;Fucking symlinks&lt;/h3&gt;

&lt;p&gt;OK, this is harder, but all your fault. You have symlinks in your repo, presumably to
share code between projects. Bad. Share code through a package manager, a submodule,
or some other means, but not through a symlink.&lt;/p&gt;

&lt;p&gt;This is a problem when your repository split makes a symlink invalid, since Git
stores symlinks as a file with its only contents a path.&lt;/p&gt;

&lt;p&gt;To fix this, we’ll convert all symlinks into hard links, which Git will then
treat as any other file and commit its contents.&lt;/p&gt;

&lt;p&gt;Convert all symlinks to hard links (if the symlinks are relative paths):&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;git filter-branch -f --tree-filter \
&apos;find . -type l -exec bash -c &apos;&quot;&apos;&quot;&apos;ln -f &quot;$(dirname &quot;$0&quot;)/&quot;&quot;$(readlink -n &quot;$0&quot;)&quot; &quot;$0&quot;&apos;&quot;&apos;&quot; {} \;&apos; \
--prune-empty -- HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the paths are absolute, WTF? How the hell did that ever work to begin with??&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;empty-commits&quot;&gt;Empty commits&lt;/h3&gt;

&lt;p&gt;If for some reason you have empty commits (maybe you forgot a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--ignore-unmatch&lt;/code&gt; ?),
you can remove them with a special &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--commit-filter&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;git filter-branch --commit-filter &apos;git_commit_non_empty_tree &quot;$@&quot;&apos; HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;the-initial-commit-is-still-empty-what-gives&quot;&gt;The initial commit is still empty, what gives?&lt;/h4&gt;

&lt;p&gt;That’s the only price your going to pay for not doing the right thing to start, so
be OK with it. Your initial commit is most likely going to be an empty one saying
“Initial commit” or whatever you said.&lt;/p&gt;

&lt;p&gt;You could rebase your entire repository (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase --interactive --root&lt;/code&gt;)
but if you have any legitimate merge commits you’ll find yourself attempting to merge
years old code in the right order. It’s not worth it.&lt;/p&gt;

&lt;h3 id=&quot;fixing-author-info&quot;&gt;Fixing author info&lt;/h3&gt;

&lt;p&gt;If you notice certain committers used a non-company email, or there are commits
from non-human accounts, you can use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--env-filter&lt;/code&gt; to rewrite author and 
committer name and emails. &lt;a href=&quot;https://help.github.com/articles/changing-author-info&quot;&gt;GitHub’s Help site has a good example of this&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;holy-crap-i-deleted-the-wrong-thingeverything&quot;&gt;Holy crap I deleted the wrong thing/everything!&lt;/h3&gt;

&lt;p&gt;No problem! If anything goes wrong, you can undo the last &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter-branch&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;git reset --hard refs/original/refs/heads/master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;next-steps&quot;&gt;Next steps&lt;/h3&gt;

&lt;p&gt;After you’ve got all your new shiny respositories how you want them, you’re may not
be entirely done. Some things that you probably need to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create new CI or deployment jobs to work against new repos&lt;/li&gt;
  &lt;li&gt;Reference GitHub issues in commits? Well, now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#1234&lt;/code&gt; points to your new repo,
not the old one. To reference an issue in a different repo than the current one,
use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user/repo#1234&lt;/code&gt; (and make it a habit to always reference them like that).
I’ll leave it to the reader to figure out how to rewrite commit messages from
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#1234&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user/repo#1234&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Delete old code from old repo, and put a message up on your old repo telling
visitors where to look for the new repo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy history rewriting!&lt;/p&gt;
</description>
				<pubDate>Thu, 17 Jul 2014 18:19:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/splitting-up-a-git-repo</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/splitting-up-a-git-repo</guid>
			</item>
		
			<item>
				<title>Sparklines in WPF and Silverlight</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
&lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_OqCZhp9yI0Q/TcdqGOwvLII/AAAAAAAAAXw/kv7ipoVOWWU/s1600-h/image%5B38%5D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;http://lh5.ggpht.com/_OqCZhp9yI0Q/TcdqHYBck1I/AAAAAAAAAX0/TfMiLAp5p9w/image_thumb%5B28%5D.png?imgmax=800&quot; width=&quot;480&quot; height=&quot;240&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One seemingly-trivial-yet-recurring problem in financial software is the need for a live-updating line-chart. However, from multiple conversations with &lt;a href=&quot;http://lab49.com&quot; target=&quot;_blank&quot;&gt;Lab49&lt;/a&gt; folks, as well as from experience during my first project, I’ve learned that most WPF/Silverlight charting packages fall short in various ways, especially if you’re updating their data frequently. Seems like everyone just rolls their own line chart and tailors it to each project, but doesn’t share it for some reason. I’d like to break that trend by sharing and early version of &lt;a href=&quot;http://github.com/jschementi/sparkline&quot; target=&quot;_blank&quot;&gt;my own sparkline control for WPF and Silverlight&lt;/a&gt;.&lt;/p&gt; &lt;p align=&quot;left&quot;&gt;&lt;a href=&quot;http://github.com/jschementi/sparkline&quot;&gt;&lt;strong&gt;&lt;font size=&quot;3&quot;&gt;http://github.com/jschementi/sparkline&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Sample Usage:&lt;/strong&gt; &lt;/p&gt;&lt;script src=&quot;https://gist.github.com/961143.js&quot;&gt; &lt;/script&gt; &lt;p&gt;It’s implementation is very basic; &lt;a href=&quot;https://github.com/jschementi/sparkline/blob/master/Schementi.Controls.Sparkline/Sparkline.xaml.cs#L255&quot; target=&quot;_blank&quot;&gt;Sparkline.AddTimeValue&lt;/a&gt; constructs a point at the next time interval and adds it to a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.shapes.polyline.aspx&quot; target=&quot;_blank&quot;&gt;Polyline&lt;/a&gt;. You can control the sparkline’s visuals, including adding visible points along the line and showing horizontal lines for the latest/highest/lowest values. The source builds assemblies for both .NET 4.0 and Silverlight 4.&lt;/p&gt; &lt;p&gt;There are obvious features missing like rendered axis or variable x-axis (time) values, but hopefully this provides a simple starting place for anyone else needing a very simple updating line graph. &lt;/p&gt; &lt;p&gt;By the way, &lt;a href=&quot;http://decav.com/&quot; target=&quot;_blank&quot;&gt;Andre de Cavaignac&lt;/a&gt;, a colleague of mine at Lab49, and Daniel Simon shared their own a while back: &lt;a href=&quot;http://blog.lab49.com/archives/2028&quot; target=&quot;_blank&quot;&gt;Live Updating Line Graph in WPF&lt;/a&gt;. Let me know if there are any others out there.&lt;/p&gt;
&lt;/div&gt;
</description>
				<pubDate>Mon, 09 May 2011 04:15:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2011/05/sparklines-in-wpf-and-silverlight.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2011/05/sparklines-in-wpf-and-silverlight.html</guid>
			</item>
		
			<item>
				<title>MacDrive 7 with Windows 7</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
    &lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;&lt;a href=&apos;http://www.mediafour.com/products/macdrive/&apos; target=&quot;_blank&quot;&gt;MacDrive 8&lt;/a&gt; has been released, which has support for Windows 7, so the work-around explained in this post is no longer necessary. Also, people have been experiencing issues with it, so my advice is to upgrade.&lt;/p&gt;
    &lt;hr /&gt;
    &lt;p&gt;If you’re running Windows on a Mac, and you’re shuffling files between Mac OS and Windows, &lt;a href=&quot;http://www.mediafour.com/products/macdrive/&quot; target=&quot;_blank&quot;&gt;MacDrive&lt;/a&gt; is the best tool for mounting your &lt;a href=&quot;http://en.wikipedia.org/wiki/Hierarchical_File_System&quot; target=&quot;_blank&quot;&gt;HFS&lt;/a&gt; (Mac OS’s default file-system format) partitions in Windows. MacDrive costs $49.95, but is well worth it. However, MacDrive does not release versions for pre-release operating systems, and there are a couple speed bumps when trying to use MacDrive on &lt;a href=&quot;http://www.microsoft.com/windows/windows-7/&quot; target=&quot;_blank&quot;&gt;Windows 7&lt;/a&gt;. There are various version of this solution posted in a bunch of forums, but no definitive guide. Here’s exactly how I solved it:&lt;/p&gt;

    &lt;ol&gt;

        &lt;li&gt;&lt;strong&gt;MacDrive’s installer will only run on Windows XP and Vista&lt;/strong&gt;.&lt;p&gt;To have it run on Windows 7, you must run as Administrator, run in “Windows Vista” compatibility mode.&lt;/p&gt;&lt;/li&gt;

        &lt;li&gt;&lt;strong&gt;Also remove the operating system version checks the installer makes with &lt;a href=&quot;http://www.technipages.com/wp-content/uploads/2007/11/orca.Msi&quot; target=&quot;_blank&quot;&gt;Orca&lt;/a&gt;&lt;/strong&gt;. MacDrive’s installer is an self-extracting exe, so you must extract it first; using &lt;a href=&quot;http://www.7-zip.org/&quot; target=&quot;_blank&quot;&gt;7-zip&lt;/a&gt; or any other unzipping tool will do the trick. Once extracted launch Orca and open MacDrive/x86.en-US/MacDrive7.x86.en-US.msi (or the x64 version if that applies to you). Once open, look for the “LaunchCondition” table and delete all rows from it.&lt;/li&gt;

    &lt;li&gt;If you run the main setup.exe from the extracted location it will install fine, but upon reboot you will not see your Mac OS drive. This is because &lt;font color=&quot;#ff8000&quot;&gt;&lt;strong&gt;MacDrive simply doesn’t assign the drive a letter&lt;/strong&gt;&lt;/font&gt;. To do so, download &lt;a href=&quot;http://prdownloads.sourceforge.net/ext2fsd/Ext2Fsd-0.46a.zip?download&quot;&gt;Ext2Fsd&lt;/a&gt;, unzip, and run Ext2Mgr.exe. Find your HFSJ-formatted partition, right-click and select “Change Drive Letter”. Assign it a letter, exit the application.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/_OqCZhp9yI0Q/Sgno57PMYbI/AAAAAAAAAI0/Yy1xawEql14/s1600-h/image%5B9%5D.png&quot;&gt;&lt;img style=&quot;display: inline&quot; title=&quot;image&quot; alt=&quot;image&quot; src=&quot;http://lh4.ggpht.com/_OqCZhp9yI0Q/Sgno6CGWVOI/AAAAAAAAAI4/8kkXsWdsOg8/image_thumb%5B5%5D.png?imgmax=800&quot; width=&quot;400&quot; height=&quot;323&quot; /&gt;&lt;/a&gt; &lt;/li&gt;

    &lt;li&gt;&lt;strong&gt;Open up your “Computer” screen and you should see your Mac OS drive now:&lt;/strong&gt;

    &lt;p&gt;&lt;a href=&quot;http://lh6.ggpht.com/_OqCZhp9yI0Q/Sgno6dgnxaI/AAAAAAAAAI8/e4X5uluVjkA/s1600-h/image%5B15%5D.png&quot;&gt;&lt;img style=&quot;display: inline&quot; title=&quot;image&quot; alt=&quot;image&quot; src=&quot;http://lh4.ggpht.com/_OqCZhp9yI0Q/Sgno6tQIlfI/AAAAAAAAAJA/bxQwAoLZ_G4/image_thumb%5B9%5D.png?imgmax=800&quot; width=&quot;400&quot; height=&quot;62&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ol&gt;
    &lt;p&gt;Please post in the comments if this doesn’t work for you, and I’ll update the steps. Enjoy!&lt;/p&gt;
&lt;/div&gt;
</description>
				<pubDate>Tue, 12 May 2009 21:23:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2009/05/macdrive-7-with-windows-7.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2009/05/macdrive-7-with-windows-7.html</guid>
			</item>
		
			<item>
				<title>Git on Windows 7</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
&lt;p&gt;I use &lt;a href=&quot;http://gitscm.org&quot; target=&quot;_blank&quot;&gt;Git&lt;/a&gt; everyday, whether it be for &lt;a href=&quot;http://ironruby.net&quot; target=&quot;_blank&quot;&gt;IronRuby&lt;/a&gt;, &lt;a href=&quot;http://github.com/jschementi/agdlr&quot; target=&quot;_blank&quot;&gt;AgDLR&lt;/a&gt;, or random other Rails/Ruby work. Being that I work at Microsoft, I got my hands on earlier build of &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_7&quot; target=&quot;_blank&quot;&gt;Windows 7&lt;/a&gt; during the fall. Unfortuantely, git didn’t work fully on Windows 7, failing whenever a merge happened, which made push fail, as well as pull when trying to get other people’s changes). &lt;a href=&quot;http://blog.jredville.com/&quot; target=&quot;_blank&quot;&gt;Jim Deville&lt;/a&gt; has been tracking this with the Windows team, and even bringing it up to the &lt;a href=&quot;http://code.google.com/p/msysgit/&quot; target=&quot;_blank&quot;&gt;msysgit&lt;/a&gt; maintainer to see if there’s any way around this. It was looking grim, so I left my main development machine on Vista, and was sad.&lt;/p&gt;&lt;p&gt;Windows 7 Beta was released this past Friday, and I managed to download the .iso, get a Product Key, etc, at home during the day on Saturday. Now that it’s released, I’m guessing other people will have this problem ...&lt;/p&gt;&lt;p&gt;I’m not sure of the specific details behind the issue, but msysgit calls into C:\windows\system32\msvcrt.dll during a merge, and the changes to that DLL in Windows 7 breaks msysgit. Last week, &lt;a href=&quot;http://www.iunknown.com/&quot; target=&quot;_blank&quot;&gt;John Lam&lt;/a&gt; was describing the issue to John Messerly, and realized that the easiest fix would be to copy the Windows Vista msvcrt.dll to the C:\Program Files\Git\bin directory, since Windows DLL resolution will look on the PATH, and “.” is included.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/curth/default.aspx&quot; target=&quot;_blank&quot;&gt;Curt Hagenlocher&lt;/a&gt; just &lt;a href=&quot;http://twitter.com/chagenlocher/status/1112241244&quot; target=&quot;_blank&quot;&gt;reminded me of the fix&lt;/a&gt;, and it works!&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_OqCZhp9yI0Q/SWq-biEzmNI/AAAAAAAAAHA/9JoANeiZnlE/s1600-h/gitwin7%5B7%5D.png&quot;&gt;&lt;img style=&quot;display: inline&quot; title=&quot;gitwin7&quot; alt=&quot;gitwin7&quot; src=&quot;http://lh3.ggpht.com/_OqCZhp9yI0Q/SWq-cVMzCYI/AAAAAAAAAHE/w7lqk80YTsM/gitwin7_thumb%5B5%5D.png?imgmax=800&quot; width=&quot;400&quot; height=&quot;155&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Pretty awesome. Enjoy Git in Windows 7!&lt;/p&gt;
&lt;/div&gt;</description>
				<pubDate>Mon, 12 Jan 2009 03:52:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2009/01/git-on-windows-7.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2009/01/git-on-windows-7.html</guid>
			</item>
		
			<item>
				<title>Live Mesh doesn't require UAC!</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
&lt;p&gt;&lt;a title=&quot;Live Mesh Logo&quot; href=&quot;/images/flickr/2590440231_447ce421da_z.jpg&quot;&gt;&lt;img border=&quot;0&quot; alt=&quot;Live Mesh Logo&quot; src=&quot;/images/flickr/2590440231_447ce421da_z.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Today my three machines (2 Vista and 1 XP) which use &lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_Live_Core&quot;&gt;Live Mesh&lt;/a&gt; asked to be updated. No information to what the updates include ... just that they wanted to plug back into the mother ship. I thought, &amp;quot;Could this be, the infamous Live Mesh update that removes the need for &lt;a href=&quot;http://www.youtube.com/watch?v=DUPxkzV1RTc&quot;&gt;UAC&lt;/a&gt;&amp;quot;? After updating my Vista machines, I &lt;a href=&quot;http://www.howtogeek.com/howto/windows-vista/disable-user-account-control-uac-the-easy-way-on-windows-vista/&quot;&gt;disabled UAC&lt;/a&gt;, rebooted, and ... Live Mesh still worked fine! Woohoo!&lt;/p&gt;  &lt;p&gt;This should now convince more people to &lt;a href=&quot;https://www.mesh.com/Welcome/Welcome.aspx&quot;&gt;install and use Live Mesh&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;PS: I searched the &lt;a href=&quot;http://en.wikipedia.org/wiki/Series_of_tubes&quot;&gt;tubes&lt;/a&gt; for any announcement of this awesome update, and found nothing. Nothing. &lt;a href=&quot;http://www.christopherprice.net/live-mesh-updated-no-uac-required-371.html&quot;&gt;This guy&lt;/a&gt; had the same experience. However, today (a day after the update) at 11:30a a blog entry appeared on the &lt;a href=&quot;http://blogs.msdn.com/livemesh/&quot;&gt;Live Mesh blog&lt;/a&gt; announcing the &lt;a href=&quot;http://blogs.msdn.com/livemesh/archive/2008/06/18/service-update-new-build-released-2815-17.aspx&quot;&gt;service update&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Now, I suffer from the same delay-between-release-and-blogging syndrome that most project owners suffer from, but all projects are expected to have some explanation of what the release contains ... like release notes, etc. Live Mesh uses there blog as the release notes, so they have more of a &lt;strong&gt;need&lt;/strong&gt; to be on-top of their blog&lt;strong&gt;. &lt;/strong&gt;&lt;/p&gt;  
&lt;/div&gt;</description>
				<pubDate>Wed, 18 Jun 2008 21:25:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2008/06/live-mesh-doesn-require-uac.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2008/06/live-mesh-doesn-require-uac.html</guid>
			</item>
		
			<item>
				<title>Fixing Mac OS X - Leopard's Spaces</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://images.appleinsider.com/leopard-preview-spaces-2.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;&quot; src=&quot;http://images.appleinsider.com/leopard-preview-spaces-2.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;If anyone has turned on &quot;Spaces&quot; in Leopard, you&apos;ll know why Apple decided to ship it turned off; the window switcher (Command-Tab) doesn&apos;t understand Spaces, and will automatically warp you to the first space that has that application running on it. In practice, this is horrible if you have apps running on different spaces (browsers, terminal, textmate, etc).

Luckily, Apple has a way of changing that behavior! In 10.5.2 they introduced a default option to &lt;a href=&quot;http://www.macosxhints.com/article.php?story=2008021122525348&quot;&gt;disable space switching on Command-Tab&lt;/a&gt;. Open up Terminal or iTerm and type the following:
&lt;pre&gt;&lt;code&gt;defaults write com.apple.Dock workspaces-auto-swoosh -bool NO
killall Doc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will make Command-Tab only switch between applications running in the same Space. However, if you switch to an Application which is not in your current Space, it will &lt;strike&gt;still warp you to the Space where it is&lt;/strike&gt; &lt;b&gt;not&lt;/b&gt; warp you between spaces; you much always switch spaces manually. Regardless, it&apos;s much better and makes Spaces much more usable. Though, Workspaces in Gnome still feel much better.&lt;/p&gt;
&lt;/div&gt;</description>
				<pubDate>Mon, 31 Mar 2008 02:34:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2008/03/fixing-mac-os-x-leopards-spaces.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2008/03/fixing-mac-os-x-leopards-spaces.html</guid>
			</item>
		
			<item>
				<title>NTFS Symbolic Link</title>
				<description>&lt;a href=&quot;/images/posts/vista-726747.jpg&quot;&gt;&lt;img src=&quot;/images/posts/vista-726747.jpg&quot;&gt;&lt;/a&gt;

&lt;p&gt;I almost hate to say it, but the more I use Vista for my day-to-day work the more I hate it less. Yes, that was a lot of small hates.&lt;/p&gt;

&lt;p&gt;Vista now supports symbolic/hard links like POSIX systems do (*nix, bsd, etc). This is amazing, as I use them like crazy on my Ubuntu and Leopard machines.&lt;/p&gt;

&lt;p&gt;It&apos;s as easy as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\&amp;gt;mklink /d bar c:\windows&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;More info: &lt;a href=&quot;http://en.wikipedia.org/wiki/NTFS_symbolic_link&quot;&gt;http://en.wikipedia.org/wiki/NTFS_symbolic_link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I stumbled upon this while trying to set up the Zune software and iTunes (on Leopard) to pull from the same music library ... on yet another machine. On Leopard, I simply put a symlink to where my music library is mapped, so it looked something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$/Users/jimmy&amp;gt;ln -s /Volumes/jimmy/Music/iTunes Music/iTunes&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This requires I have my shared library mounted to that volume already, so I created a little &lt;a href=&quot;http://en.wikipedia.org/wiki/Automator_%28software%29&quot;&gt;automator&lt;/a&gt; script to mount &lt;code&gt;smb://jimmy-zeus/jimmy&lt;/code&gt; to &lt;code&gt;/Volumes/jimmy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Vista, this is simply one step. You can make the symlink directly to a SMB file-share! (Please someone correct me if you can do this in *nix ... I&apos;ll promise to feel like an idiot =P).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\Users\jimmysch&amp;gt;mklink /D iTunes \\jimmy-zeus\jimmy\Music\iTunes\iTunes Music&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty freakin&apos; cool!&lt;/p&gt;

&lt;p&gt;[Update] Ok, maybe SMB file-share symlinks aren&apos;t so cool; as explorer.exe doesn&apos;t understand them and will hang the UI if the server doesn&apos;t respond right away when navigating to a folder with &lt;strong&gt;ANY SMB SYMLINK&apos;d FOLDERS!&lt;/strong&gt; And if you don&apos;t have access to the server ... you must wait for the 60 second timeout to get control of the window again. Ugh. Use wisely ...&lt;/p&gt;
</description>
				<pubDate>Sun, 23 Dec 2007 06:51:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/12/ntfs-symbolic-link.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/12/ntfs-symbolic-link.html</guid>
			</item>
		
			<item>
				<title>Upgrading Assistment to Rails 2.0</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://b.lesseverything.com/assets/2007/10/4/rails2.0.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;&quot; src=&quot;http://b.lesseverything.com/assets/2007/10/4/rails2.0.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-size:78%;&quot;&gt;image linked from b.lesseverything.com
&lt;/span&gt;&lt;/div&gt;
Today I spent some time upgraded Assistment (&lt;a href=&quot;http://assistment.org/&quot;&gt;http://assistment.org&lt;/a&gt;) to Rails 2.0. I made the mistake of upgrading Rails before changing anything, and then fixing the errors one by one ... oy. So, I&apos;ll quickly go over what I had to do to get stuff working again.
&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-large;&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:180%;&quot;&gt;Fix deprecation warnings in 1.2.6&lt;/span&gt;&lt;/div&gt;&lt;div&gt;If you haven&apos;t upgraded yet, make sure you&apos;re on Rails 1.2.6 and get rid of your deprecated API calls: &lt;a href=&quot;http://www.rubyonrails.org/deprecation&quot;&gt;http://www.rubyonrails.org/deprecation&lt;/a&gt;. To easily find your deprecated usages grab the rake task from this site: &lt;a href=&quot;http://www.slashdotdash.net/articles/2007/12/03/rails-2-upgrade-notes&quot;&gt;http://www.slashdotdash.net/articles/2007/12/03/rails-2-upgrade-notes&lt;/a&gt;. And of course, make sure your tests pass and your app actually runs before moving on!
&lt;/div&gt;&lt;div&gt;
Keep in mind some pretty useful parts of Rails have been pulled out into plugins, which you can find at &lt;a href=&quot;http://svn.rubyonrails.org/rails/plugins/&quot;&gt;http://svn.rubyonrails.org/rails/plugins/&lt;/a&gt;. I had to install acts_as_list, acts_as_tree, classic_pagination (though, we really need to move to will_paginate!), and in_place_editing. I also had to spend time updating my forms to use the block-notation rather that start/end form tags. That was annoying.

One plugin I had trouble with was acts_as_paranoid. It calls &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&apos;courier new&apos;;&quot;&gt;construct_count_options_from_legacy_args&lt;/span&gt;, which is deprecated, but I have not found an update to the plugin. To fix it, I had to add that method to the plugin. I left the deprecation notice in there to remind me to fix it =)

Also, if you used &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&apos;courier new&apos;;&quot;&gt;strip_tags&lt;/span&gt; in you&lt;span style=&quot;font-size:100%;&quot;&gt;r &lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;font-size:100%;&quot; &gt;model&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt; (shush, I had my reason: I used it since I stored HTML in the database and I wanted a nice way to clean it), you have to include &lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;;font-family:&apos;courier new&apos;;font-size:100%;&quot;  &gt;A&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&apos;courier new&apos;;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;ctionView::Helpers::SanitizeHelpe&lt;/span&gt;r&lt;/span&gt; in your model; just including &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&apos;courier new&apos;;&quot;&gt;ActionView::Helpers::TextHelper&lt;/span&gt; won&apos;t cut it.

&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:180%;&quot;&gt;Upgrading Rails&lt;/span&gt;
&lt;pre&gt;&lt;code&gt;gem update rails&lt;/code&gt;&lt;/pre&gt; should do the trick for upgrading you. I had some problems upgrading on Leopard, so I had to gem remove rails and the active*/action* gems before running &quot;gem install rails&quot;. Even that failed the first 2 times with 404 errors for finding certain gems, but the 3rd time it worked.&lt;/div&gt;&lt;div&gt;
&lt;pre&gt;&lt;code&gt;rake rails:update&lt;/code&gt;&lt;/pre&gt;Run that in your project to upgrade your configs, javascripts, and scripts. I took the extra step and generated a new rails project and merged any new config changes into Assistment. This was mainly environment.rb, and the extremely useful addition of a initializers directory for application config.

&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:180%;&quot;&gt;Running Two point Oh!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;(Note: to use ruby-debug you don&apos;t need to manually set it up in environment.rb. Simply run ./script/server --debugger to enable debugging with the &quot;debugger&quot; method. Yep, that simple.)

Run your app/tests and your on Rails 2.0! If anyone has any additional issues, &lt;a href=&quot;http://www.google.com/&quot;&gt;google&lt;/a&gt; is your friend.&lt;/div&gt;
&lt;/div&gt;</description>
				<pubDate>Sun, 16 Dec 2007 08:56:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/12/upgrading-assistment-to-rails-20.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/12/upgrading-assistment-to-rails-20.html</guid>
			</item>
		
			<item>
				<title>Rounded corners with Transcorners</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
I just spent the past hour and a half trying to get simple rounded corners using &lt;a href=&quot;http://inviz.ru/moo/transcorners/&quot;&gt;Transcorners&lt;/a&gt;, and I wanted to let everyone know about a little &quot;gotcha&quot; so no one else will waste all that time like I did.

If you are experiencing the background of your rounded div not being rounded ... and the border BOTH rounding and not ...

&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;/images/posts/transcorner_error-732724.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;/images/posts/transcorner_error-732724.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;... then you are experiencing the same problem I did. To fix this, simply make sure the background-color of one of the parent elements is set. In my case, nothing had it set, including the body ...
&lt;pre&gt;body {
 background-color: white;
}&lt;/pre&gt;... this will make sure the background color is set and you will achieve the correct rounded corner effect:
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;/images/posts/transcorners-779745.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;/images/posts/transcorners-779745.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
</description>
				<pubDate>Tue, 24 Apr 2007 23:42:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/04/using-transcorners.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/04/using-transcorners.html</guid>
			</item>
		
			<item>
				<title>Book Reviews - Head First OOA&amp;D and Rails Recipies</title>
				<description>&lt;p&gt;Check out my review of &lt;b&gt;Head First Object-Oriented Analysis &amp;amp; Design&lt;/b&gt; on &lt;a href=&quot;http://www.ibm.com/&quot;&gt;IBM&lt;/a&gt;s &lt;a href=&quot;http://www-304.ibm.com/partnerworld/wps/servlet/ContentHandler/swg_ben_res_rational_edge_ezine&quot;&gt;Rational Edge e-zine&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://web.archive.org/web/20080314184036/http://www-128.ibm.com/developerworks/rational/library/feb07/reader/index.html&quot;&gt;Head First OOA&amp;amp;D Review&lt;/a&gt;
&lt;/ul&gt;

&lt;p&gt;Also, I don&apos;t think I ever posted about my review of Rails Recipes, check that out!&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://web.archive.org/web/20070703163531/http://www-128.ibm.com/developerworks/rational/library/nov06/schementi/index.html&quot;&gt;Rails Recipes Review&lt;/a&gt;
&lt;/ul&gt;
</description>
				<pubDate>Thu, 22 Feb 2007 18:48:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/02/book-review-head-first-ooa.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/02/book-review-head-first-ooa.html</guid>
			</item>
		
			<item>
				<title>Assistments</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
    &lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://assistments.org&quot;&gt;&lt;img src=&quot;/images/posts/logo-half-745025.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;This year, I&apos;ll be working as the Lead Developer in Neil Heffernan&apos;s Artificial Intelligence Lab, which is part of WPI&apos;s Computer Science Department. This lab isn&apos;t a traditional lab, they actually make a product! It&apos;s called &lt;a href=&quot;http://assistments.org&quot;&gt;ASSISTments&lt;/a&gt;, an intelligent tutoring system that&apos;s being used in MA schools today. Undergraduate and graduate students from WPI primarily built it, but Carnegie Mellon also collaborates in research.&lt;/p&gt;

    &lt;p&gt;We&apos;re working on a new version of the system to enable more scaffolding of questions, more question types, and just faster development in general. The current system is written in Java, and we&apos;re rebuilding it with Ruby on Rails. Some of the new features we&apos;re adding are effort calculations, content feedback, calculator support, content versioning. Check out the progress blog at &lt;a href=&quot;http://assistment.blogspot.com/&quot;&gt;http://assistment.blogspot.com&lt;/a&gt;.&lt;/p&gt;

    &lt;p&gt;This effort will be a case study for my master&apos;s thesis about productizing a research project.&lt;/p&gt;
&lt;/div&gt;
</description>
				<pubDate>Mon, 19 Feb 2007 02:51:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/02/assistment.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/02/assistment.html</guid>
			</item>
		
			<item>
				<title>Nichum.com</title>
				<description>&lt;img src=&quot;/images/posts/banner-737174.png&quot;&gt;
&lt;p&gt;I&apos;m launching a website with Alex Kantrowitz that will help a lot of people in mourning.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href=&quot;http://nichum.com&quot;&gt;Nichum.com&lt;/a&gt; to see what it&apos;s about.&lt;/p&gt;
</description>
				<pubDate>Sun, 24 Dec 2006 01:34:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2007/12/nichumcom.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2007/12/nichumcom.html</guid>
			</item>
		
			<item>
				<title>Articles for CLR Inside Out</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
    &lt;p&gt;I got two articles published in MSDN Magazine!&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/archive/msdn-magazine/2006/october/clr-inside-out-ironpython&quot;&gt;IronPython&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/archive/msdn-magazine/2008/february/clr-inside-out-dynamic-languages-and-silverlight&quot;&gt;Dynamic Language in Silverlight&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
</description>
				<pubDate>Wed, 06 Sep 2006 05:26:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2006/09/clr-inside-out.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2006/09/clr-inside-out.html</guid>
			</item>
		
			<item>
				<title>Starline</title>
				<description>&lt;div class=&quot;post-content&quot;&gt;
    &lt;div style=&quot;margin-bottom: 10px; text-align: center;&quot;&gt;&lt;img src=&quot;/images/flickr/204128284_ed61b91423_w.jpg&quot; /&gt;&lt;/div&gt;
    &lt;p&gt;Yesterday I launched Starline (&lt;a href=&quot;http://starline.schementec.com&quot;&gt;starline.schementec.com&lt;/a&gt;), a web-based point-of-sale app. It was initially written in Visual Basic for a specific restaurant, a project Mike Veilleux started and I continued. We’ve moved between so many different iterations, but now it&apos;s landed on a web app, and feels much better. Check it out!&lt;/p&gt;

&lt;/div&gt;
</description>
				<pubDate>Wed, 19 Jul 2006 09:10:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2006/07/starline-revealed.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2006/07/starline-revealed.html</guid>
			</item>
		
			<item>
				<title>Hard Drive Recovered!</title>
				<description>&lt;p&gt;&lt;a href=&quot;/2005/10/hard-drive-failure.html&quot;&gt;&lt;strong&gt;Follow up from previous post&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was about to go to Fedex to send my hard drive, but I just couldn’t believe that this was my only option.  To cut to the chase, I got all my data back!!!  All thanks to &lt;a href=&quot;http://www.active-undelete.com/&quot;&gt;Active@ UNDELETE&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Active@ is a Software Company specializing in data recovery.  They make 2 tools that I used, &lt;a href=&quot;http://www.partition-recovery.com/&quot;&gt;Partition Recovery&lt;/a&gt; and &lt;a href=&quot;http://www.active-undelete.com/&quot;&gt;UNDELETE&lt;/a&gt;, to save my files.  I really only needed UNDELETE but Partition Recovery let me see my files and give me hope that a bomb hitting my room is much worse.&lt;/p&gt;

&lt;p&gt;I also bought a &lt;a href=&quot;http://reviews.cnet.com/external-hard-drives/maxtor-onetouch-ii-300gb/4505-3190_7-31121421.html&quot;&gt;Maxtor OneTouch II 300GB portable hard drive&lt;/a&gt;.  This thing is pretty sweet.  It not only a lot of storage, but it comes with Retrospect which will let you schedule backups.  It also has this button on the front of the drive that when pressed will backup and newly created/changed files.  Sweet stuff.&lt;/p&gt;

&lt;p&gt;Anyway, now I can get on with my life. Back up regularly. definitely a huge learning experience for me about how hard drives work.&lt;/p&gt;
</description>
				<pubDate>Fri, 07 Oct 2005 15:25:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2005/10/hard-drive-recovered.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2005/10/hard-drive-recovered.html</guid>
			</item>
		
			<item>
				<title>Hard Drive Failure</title>
				<description>&lt;p&gt;&lt;img src=&quot;/images/flickr/52339263_ab10028255_b.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Friday night my computer started to act weird.  I backed up all my data to another location of the drive where it would be safe, but I didn’t think to get it off my computer and onto something else like another hard drive or DVDs.  That was my mistake.  Something went wrong and I lost access to all my files.  There are still on my hard drive but I can’t get to them.&lt;/p&gt;

&lt;p&gt;I’m thinking of sending the hard drive to a data recovery company to see if they can fix it, but it’s going to cost more than $1K  to recover the data.&lt;/p&gt;

&lt;p&gt;Moral of the story … back up your data!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update &lt;a href=&quot;/2005/10/hard-drive-recovered.html&quot;&gt;Got my data restored!&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 05 Oct 2005 19:04:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2005/10/hard-drive-failure.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2005/10/hard-drive-failure.html</guid>
			</item>
		
			<item>
				<title>Ode to Joystick - Newspaper Interview</title>
				<description>&lt;p&gt;&lt;a href=&quot;http://web.archive.org/web/20050212125824/http://www.gdc.wpi.edu/~blaze/article.html&quot;&gt;Ode to joystick - Worcester Telegram and Gazette.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s a mirror of the article about the new Interactive Media and Game Development (IMGD) major at WPI. Being the head of the Game Development Club at WPI, Chris and I were interviewed for our take on the major.&lt;/p&gt;
</description>
				<pubDate>Tue, 23 Nov 2004 03:21:00 +0000</pubDate>
				<link>http://jimmy.schementi.com/2004/11/ode-to-joystick.html</link>
				<guid isPermaLink="true">http://jimmy.schementi.com/2004/11/ode-to-joystick.html</guid>
			</item>
		
	</channel>
</rss>
