<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>bl.ogtastic - Home</title>
  <id>tag:b.logi.cx,2009:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://b.logi.cx/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://b.logi.cx/" rel="alternate" type="text/html"/>
  <updated>2009-07-23T20:14:54Z</updated>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>rickbradley</name>
    </author>
    <id>tag:b.logi.cx,2009-07-17:2471</id>
    <published>2009-07-17T18:58:00Z</published>
    <updated>2009-07-23T20:14:54Z</updated>
    <category term="crunkfish"/>
    <category term="hoedown"/>
    <category term="nashvegas"/>
    <category term="ruby"/>
    <link href="http://b.logi.cx/2009/7/17/nashville-hi-lites-for-the-ruby-hoedown" rel="alternate" type="text/html"/>
    <title>Nashville Hi-Lites for the Ruby Hoedown</title>
<content type="html">
            &lt;p&gt;Seeing as how Nashvegas is the venue for this year&#8217;s &lt;a href=&quot;http://www.rubyhoedown.com/&quot;&gt;Ruby Hoedown&lt;/a&gt;, &lt;em&gt;and&lt;/em&gt; it&#8217;s OGC&#8217;s hometown, we thought we&#8217;d jot down some notes to help our Hoedown homies make the best of their time in NV.  So, without further ado, here&#8217;s the cream of the crop:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UPDATED&lt;/em&gt;:  No list is complete without coffee shops!  Also added a couple other random bits.&lt;/p&gt;

&lt;h3&gt;Greenways&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Nashville Greenways system provides walkable and bikeable paved trails connecting many parts of downtown.  There are greenways that pass near the Opryland Hotel and connect with downtown Nashville.  &lt;a href=&quot;http://www.nashville.org/greenways/&quot;&gt;Greenways map&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Entertainment / Events&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/atmos/224242295/&quot;&gt;&lt;img src=&quot;http://farm1.static.flickr.com/90/224242295_0a623a080b.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pair Programming w/ NashDL &amp;amp; OGC &#8211; if you&#8217;re in town during the pre-Hoedown week and want to get together to do some pair programming with peeps from the Nashville&#8217;s Dynamic Languages Group and/or OG Consulting, drop a line to ogc@ogtastic.com or sign on to #nashdl on freenode.  There may even be the possibility of during-the-week accommodations for a person or few.&lt;/li&gt;
&lt;li&gt;Thursday night, if history is any guide, a monthly free-beer mixer at Centre{source}, a local web shop, prime for conversion to the Ruby Way.  Details as they emerge.&lt;/li&gt;
&lt;li&gt;Friday night Hoedown party:  Jeremy will have details forthcoming&#8230;&lt;/li&gt;
&lt;li&gt;Saturday night OGC-hosted party:  Free beer, live music, dead music, yard games, rubyists, anarchists, etc.  Details forthcoming.&lt;/li&gt;
&lt;li&gt;Cheatham County Fair demolition derby - tentatively, Thursday night, $6 fair admission unless they&#8217;ve changed ticket prices&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wilsoncountyfair.net/competitions/motorized-events/demolition-derby&quot;&gt;Wilson County Fair demolition derby&lt;/a&gt; - Friday and Saturday night &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.myspace.com/thewednesdaynightoldtimejam&quot;&gt;Wednesday night Old Time Jam&lt;/a&gt; at the &lt;a href=&quot;http://www.myspace.com/the5spotnashville&quot;&gt;5 Spot&lt;/a&gt; .  If you are a musician and are in town on Wednesday night, you MUST be here with your instrument(s).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.belcourt.org/&quot;&gt;The Belcourt Theater&lt;/a&gt; - good independent theater down in Hillsboro Village; everything from art films to independent films to classic westerns; have a beer at your seat.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Music&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/an0nym0usmuse/172613064/&quot;&gt;&lt;img src=&quot;http://farm1.static.flickr.com/76/172613064_6a7fc42ade.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.stationinn.com/&quot;&gt;The Station Inn&lt;/a&gt; - bad-ass bluegrass, all shows. &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.wildhorsesaloon.com&quot;&gt;The Wildhorse Saloon&lt;/a&gt; -   Charlie Daniels Band (thur.), 38 Special (fri.).  I&#8217;m just sayin&#8217;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.opry.com/&quot;&gt;The Grand Ol&#8217; Opry&lt;/a&gt; - near the hotel; shows every Friday and Saturday night&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.3rdandlindsley.com/&quot;&gt;3rd and Lindsley&lt;/a&gt; - Some great acts turn up here quite frequently.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.myspace.com/theendnashville&quot;&gt;The End&lt;/a&gt; - one of Nashville&#8217;s many non-Country venues.  Everyone and their punk-rock grandma has played here.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.exitin.com/&quot;&gt;The Exit/In&lt;/a&gt; - Another storied (and even famous) non-Country venue, check their calendar.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.bluebirdcafe.com/&quot;&gt;The Bluebird Cafe&lt;/a&gt; - Famous for breaking in new stars.  Always good music.&lt;/li&gt;
&lt;li&gt;Be sure to check the &lt;a href=&quot;http://www.nashvillescene.com/calendar&quot;&gt;Nashville Scene calendar&lt;/a&gt; and the &lt;a href=&quot;http://nashville.metromix.com/calendar/home/August-2009&quot;&gt;Nashville Metromix calendar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;honky tonkin&#8217;.  (You probably won&#8217;t be sad if you start at &lt;a href=&quot;http://www.robertswesternworld.com/&quot;&gt;Robert&#8217;s&lt;/a&gt;.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Food&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/atmos/tags/crunk/&quot;&gt;&lt;img src=&quot;http://farm1.static.flickr.com/89/217013330_1d291b1d4c.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lovelesscafe.com/&quot;&gt;The Loveless Cafe&lt;/a&gt; - them&#8217;s some good-ass biscuits.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.woodlandsnashville.com/&quot;&gt;Woodland&#8217;s Vegetarian Indian Cuisine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.eastsidefish.com/&quot;&gt;Eastside Fish&lt;/a&gt; - aka, &#8220;The Crunkest Fish in Town&#8221;.  Brave &#8220;the King Fish&#8221;.  &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rotiers.com/&quot;&gt;Rotier&#8217;s&lt;/a&gt; - classic Meat &amp;amp; 3.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.wheresthesign.com/&quot;&gt;Las Paletas&lt;/a&gt; - excellent Mexican popsicles&#8230; you might also find them at Bongo Java, Fido&#8217;s and a few other random locales.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tinyurl.com/m64c9k&quot;&gt;Monell&#8217;s&lt;/a&gt; - sit-down-pass-the-biscuits Southern style dining.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nashvillescene.com/locations/marys-old-fashioned-pit-barbecue-20424/&quot;&gt;Mary&#8217;s Open Pit BBQ&lt;/a&gt; - mmmmmm.  Open way late, cures what ails ya: like eatin&#8217; a smoked rack of &#8216;tussin.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jacksbarbque.com/&quot;&gt;Jack&#8217;s BBQ&lt;/a&gt; - the Trinity Lane location is the bomb, but the lower Broadway location is prime.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tinyurl.com/mae85e&quot;&gt;The Hermitage Cafe&lt;/a&gt; - Wow, you must be out late drinking. &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pansouth.net/southstreet/index.php&quot;&gt;Southstreet&lt;/a&gt; - Parking may be tight but the pulled pork is solid.  Front page of lunch menu changes daily, set nightly menu.  Open air seating in nice weather, upstairs and downstairs bar.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jamaicawaycatering.com/&quot;&gt;Jamaica Way&lt;/a&gt; - good Jamaican food in the Farmer&#8217;s Market (see also Bicentennial Mall)&lt;/li&gt;
&lt;li&gt;Princes Hot Chicken Shack / 123 Ewing Drive / Nashville, TN  37027 / 615-226-9442&lt;/li&gt;
&lt;li&gt;Bolton&#8217;s Spicy Chicken &amp;amp; Fish / 624 Main Street / Nashville, TN 37206 /  615-254-8015&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Boozing&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/osmium/13500622/&quot;&gt;&lt;img src=&quot;http://farm1.static.flickr.com/9/13500622_ad6f966221.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lower Broadway&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.broadwaybrewhouse.net/web/&quot;&gt;The Broadway Brewhouse&lt;/a&gt; - great selection of beers, multiple locations, good jukebox, wifi; the midtown location is considered by some to be the best bar in Nashville&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.beerknurd.com/&quot;&gt;The Flying Saucer&lt;/a&gt; - huge beer selection, wifi, worth a visit&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.yelp.com/biz/villager-tavern-nashville&quot;&gt;The Villager Pub&lt;/a&gt; - great bar, great jukebox, great darts bar, so smoky you will throw away your clothes.  Free dog bowl of beer on your birthday.  You&#8217;re in luck if Kevin is tending bar.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.springwatersupperclub.com/&quot;&gt;The Springwater&lt;/a&gt; - the consummate dive bar&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.familywash.com/&quot;&gt;The Family Wash&lt;/a&gt; - East Nashville. Donald Ball recommends the &#8220;Pint &amp;amp; Pie&#8221;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.boscosbeer.com/&quot;&gt;Bosco&#8217;s&lt;/a&gt; - high octane local microbrews in Hillsboro Village.  Start here and stumble to the Villager.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.blackstonebrewery.com/&quot;&gt;Blackstone&lt;/a&gt; - another local brewpub with pretty good food to boot.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.yazoobrew.com/&quot;&gt;Yazoo&lt;/a&gt; - Nashville&#8217;s answer to Sierra Nevada?  Regardless, hanging out in their tap room is a good time.  &lt;a href=&quot;http://www.yazoobrew.com/hours.html&quot;&gt;Limited hours.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.12southtaproom.com/&quot;&gt;12 South Taproom&lt;/a&gt; - Good beer selection, great front patio, good food, great live music.  Within walking distance of the 12th South Portland Brew and Frothy Monkey.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://3crowbar.com/crow/&quot;&gt;3 Crow Bar&lt;/a&gt; - Great East Nashville bar, food, pints, open air, convenient to many of the &#8220;5 points&#8221; attractions.  See also the &lt;a href=&quot;http://www.myspace.com/the5spotnashville&quot;&gt;5 Spot&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Coffee Shops&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/amberlrhea/2258025993/&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2380/2258025993_b27eae64a5.jpg?v=0&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.bongojava.com/&quot;&gt;Fido&lt;/a&gt; - High-traffic Hillsboro Village coffee shop (see also, Bosco&#8217;s and the Villager).  Great food for a coffee shop, part of the Bongo Java empire, hence pretty good coffee.  A few beer selections, but for real beer walk across the street.  Good wifi, but power outlets are very scarce (laptop row up front and a couple near the back entrance).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.frothymonkeynashville.com/&quot;&gt;Frothy Monkey&lt;/a&gt; - Great 12 South coffee shop, good food, good coffee, good wifi, nice atmosphere, nice deck.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tinyurl.com/np77qh&quot;&gt;J-J&#8217;s Market and Cafe&lt;/a&gt; - A NashDL favorite.  Good coffee, great tea selection, impressive beer selection.  Wifi is good but can get slow if there are a lot of college students hanging out.  Within crawling distance of the Broadway Brewhouse and a bevy of decent Vanderbilt-area restaurants.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.bongojava.com/&quot;&gt;Bongo Java&lt;/a&gt; - Decent food, good coffee, ok wifi, a popular place to hang out.  NashDL does Saturday morning brunches here (when there&#8217;s no Hoedown to compete with).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.portlandbrewcoffee.com/&quot;&gt;Portland Brew&lt;/a&gt; - 3 locations:
&lt;ul&gt;
&lt;li&gt;12th South - Had been under some renovations, but worth checking out &#8211; very popular, good coffee, good wifi, may have some food these days.  Convenient to various attractions on 12 South.&lt;/li&gt;
&lt;li&gt;Murphy Road/West End - Small, good coffee, good wifi, not much in the way of food.  A good pre- (or post-) Woodland&#8217;s stop.&lt;/li&gt;
&lt;li&gt;East Nashville - this is a two-story affair, fairly new, across the street from Ugly Mugs, and near some decent East Nashville eats.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.uglymugsnashville.com/html_ver/&quot;&gt;Ugly Mugs&lt;/a&gt; - close to the Portland Brew East Nashville location, good wifi, good coffee.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cafecoco.com/&quot;&gt;Cafe Coco&lt;/a&gt; - 24 hours, also has a front deck and back room.  Coffee, teas, beer on tap, food.  Wifi has been known to be spotty, but a lively locale with a diverse crowd.  Your best late night bet.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://crema-coffee.com/&quot;&gt;Crema&lt;/a&gt; - Small, but the coffee is excellent, decent snacks, and great wifi.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dunnbros.com/locate_results.asp?location_id=86&quot;&gt;Dunn Brothers&lt;/a&gt; - Downtown, limited hours, but great food, coffee, and wifi.  A really good environment if you can catch them when they&#8217;re open.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Attractions&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/powellizer/872909379/&quot;&gt;&lt;img src=&quot;http://farm2.static.flickr.com/1263/872909379_9318b3450d.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.fristcenter.org/site/default.aspx&quot;&gt;The Frist Center for the Visual Arts&lt;/a&gt; - Nashville&#8217;s art museum.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nashville.gov/parthenon/&quot;&gt;The Parthenon&lt;/a&gt; - if you&#8217;ve never seen this, you must.  Significant contributor to Nashville&#8217;s high national &#8220;WTF&#8221; ranking.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.countrymusichalloffame.com/&quot;&gt;The Country Music Hall of Fame and Museum&lt;/a&gt; - Twang.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ryman.com/&quot;&gt;The Ryman Auditorium&lt;/a&gt; - Historic venue, and a great, if expensive, place to see a show.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tennessee.gov/environment/parks/Bicentennial/&quot;&gt;Bicentennial Mall&lt;/a&gt; - outdoor craziness including fountains, capitol, railroad bridge, a Tennessee you can walk on, push the big stone globe, Art Bell-era &#8220;spaceship landing zone&#8221;, etc.; near the Farmer&#8217;s Market&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mosaicartsource.wordpress.com/2007/02/01/dragon-mosaic-sculpture-fannie-may-dees-park-nashville-tennessee/&quot;&gt;Dragon Park&lt;/a&gt; - aka &#8220;Fannie Mae Dees Park&#8221;, a nice park near Hillsboro Village (aka coffee, beer, food, fun) with an awesome dragon covered in mosaic tile.&lt;/li&gt;
&lt;li&gt;Dagohir weirdos in &lt;a href=&quot;http://tinyurl.com/l3w3a4&quot;&gt;Elmington Park&lt;/a&gt; on saturday morning.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Outdoors&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/brent_nashville/144460855/&quot;&gt;&lt;img src=&quot;http://farm1.static.flickr.com/52/144460855_3f4e94b3d4.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two Rivers Park (frisbee golf, skate/bmx park, wave pool), not far from the hotel&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nps.gov/NATR&quot;&gt;Natchez Trace Parkway&lt;/a&gt; - 444 mile road, starting at the Loveless Cafe and ending in deep Mississippi.  Nice drive, bicycling (you can rent a bike at the Loveless Cafe), hiking, views off a gorge bridge, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.radnorlake.org/welcome.html&quot;&gt;Radnor Lake&lt;/a&gt; - great hiking, you will probably need a car&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nashville.org/parks/locations/warner.htm&quot;&gt;Warner Parks&lt;/a&gt; - great hiking, near Loveless Cafe, you will need a car&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nashville.org/parks/locations/beaman.htm&quot;&gt;Beaman Park&lt;/a&gt; - great hiking, you will need a car&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nashville.org/parks/locations/bellsbend.htm&quot;&gt;Bells Bend&lt;/a&gt; - great hiking/walking, you will need a car&lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2009-04-09:2350</id>
    <published>2009-04-09T23:35:00Z</published>
    <updated>2009-05-13T13:58:45Z</updated>
    <category term="git"/>
    <category term="github"/>
    <category term="gitosis"/>
    <category term="mirroring"/>
    <category term="stinky farts"/>
    <link href="http://b.logi.cx/2009/4/9/mirroring-to-github-part-two" rel="alternate" type="text/html"/>
    <title>Can Has: Better Mirroring to the Git Hubs?</title>
<content type="html">
            &lt;p&gt;Some time ago, Rick worked out this slightly wacky scheme to handle our git repos, with backups and mirrors and suchlike. After much prodding from me, he &lt;a href=&quot;http://bl.ogtastic.com/2008/8/2/mirroring-to-github&quot;&gt;posted about it&lt;/a&gt;, accompanied by just one quite-wacky picture and a lot of code-like content.&lt;/p&gt;

&lt;p&gt;He&#8217;s no &lt;a href=&quot;http://gilesbowkett.blogspot.com/&quot;&gt;Giles Bowkett&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To help people out, we keep pushing this kind of mirroring scheme upon them when they even come close to asking about handling git repos, and we do it for their own good. We went through some headaches, we suffered from reliability and stability issues, and we wrote down some simple steps to follow and get your mirroring up and running. The problem was that each new repository created required some manual work to get the mirroring set up.&lt;/p&gt;

&lt;p&gt;But no more! Mr. Damien Lebrun (&lt;a href=&quot;http://github.com/dinoboff&quot;&gt;dinoboff on github&lt;/a&gt;) left &lt;a href=&quot;http://bl.ogtastic.com/2008/8/2/mirroring-to-github#comment-2277&quot;&gt;a comment on that old post&lt;/a&gt; telling us he had come to save the day with his Python skills and desire to scratch an itch.&lt;/p&gt;

&lt;p&gt;Now all you have to do put something like this in your gitosis.conf:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[repo freshtrack]
mirrors = git@github.com:flogic/freshtrack.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you do that, it Just Works&amp;trade;. Well, it Just Works&amp;trade; if you let Damien&#8217;s new gitosis create the repo using its fancy template with &lt;a href=&quot;http://github.com/dinoboff/gitosis/blob/ee22eab5a2848e11b9e9aa95801c6412e0d3b645/src/gitosis/templates/default/hooks/post-receive&quot;&gt;its special post-receive hook&lt;/a&gt;. If the repository already exists on your gitosis host, you&#8217;ll have to handle any hook placement yourself. Damien said as much in his comment, and it&#8217;s really obvious anyway, but that didn&#8217;t stop me from spending ten minutes trying to figure out why the mirroring wasn&#8217;t working.&lt;/p&gt;

&lt;p&gt;And it gets even better! Prompted by a question from me (or quite possibly something he was going to do anyway), he made it simple to set the mirror on multiple repositories at once. Check this out from my own gitosis.conf:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[mirror ymendel-github]
repos = dugdale flac2mp3 fsevents graphtunes markov music_conversion_observer one_inch_punch pj punch_widget truthy pj_talk truthy_talk
uri = git@github.com:ymendel/%s.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#8217;s really that simple. No more logging in to the gitosis host and futzing with repositories. (At least not once you futz with the ones that are already there. Deal with it.)&lt;/p&gt;

&lt;p&gt;To Damien Lebrun, a git-mirroring hero. Check out &lt;a href=&quot;http://github.com/dinoboff/gitosis/&quot;&gt;his fork of gitosis&lt;/a&gt; for more information, and especially check out &lt;a href=&quot;http://github.com/dinoboff/gitosis/blob/5e91b7bfc970114f699cb0b8df6ae7a816c4274d/example.conf#L55-62&quot;&gt;the example configuration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2009-04-12&lt;/strong&gt; Damien just sent word that the repetition in the group and mirror sections can be reduced with the brand-new repo aliases. Check out &lt;a href=&quot;http://github.com/dinoboff/gitosis/blob/f7792d53ada395c01aa60d33d9048a2707eed1ab/mirror.conf&quot;&gt;the example mirror config&lt;/a&gt; (and pay attention to the lines involving &#8220;public&#8221; and &#8220;@public&#8221;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>vinbarnes</name>
    </author>
    <id>tag:b.logi.cx,2009-02-24:2098</id>
    <published>2009-02-24T07:51:00Z</published>
    <updated>2009-02-24T07:53:02Z</updated>
    <link href="http://b.logi.cx/2009/2/24/a-long-way-around-for-little-to-no-gain" rel="alternate" type="text/html"/>
    <title>A Long Way Around (for little to no gain)</title>
<content type="html">
            &lt;p&gt;
Am I the &lt;em&gt;only&lt;/em&gt; one that gets miffed trying to read &lt;a href=&quot;http://gist.github.com&quot;&gt;gists&lt;/a&gt; without wordwrap? The answer is probably &lt;strong&gt;Yes&lt;/strong&gt; but that's not the point. Here at OG we opt to use gists instead of the ubiquitous Google Docs for editing everything from our bylaws to t-shirt orders. This is serious stuff. And unfortunately, I don't have a Kindle to better my reading experience.
&lt;/p&gt;

&lt;p&gt;
The point is that I usually click the &lt;tt&gt;raw&lt;/tt&gt; link, cut and paste into TextEdit and proceed to read &lt;em&gt;with&lt;/em&gt; wordwrap. Ugh. It feels like someone tossed a bag of frozen peas at my 21st digit...
&lt;/p&gt;

&lt;p&gt;The first pass of this used &lt;a href=&quot;http://appscript.sourceforge.net/&quot;&gt;appscript&lt;/a&gt; to open the contents in TextEdit after automating the downloading of the raw content. But then I found out about &lt;tt&gt;qlmanage&lt;/tt&gt;, the hidden, unsupported Quick Look simulator/debugger in &lt;a href=&quot;http://en.wikipedia.org/wiki/Mac_OS_X_v10.5&quot;&gt;Leopard&lt;/a&gt;. So of course, I used it instead! Achtung baby!

&lt;p&gt;To quote &quot;Lonesome&quot; Dave Peverett,&lt;/p&gt;

&lt;blockquote&gt;
I feel good. I feel alright!
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2009-01-19:1570</id>
    <published>2009-01-19T17:11:00Z</published>
    <updated>2009-01-22T16:22:29Z</updated>
    <category term="baby"/>
    <category term="ice"/>
    <category term="pairing"/>
    <link href="http://b.logi.cx/2009/1/19/a-day-with-an-outsider" rel="alternate" type="text/html"/>
    <title>A day with an outsider</title>
<content type="html">
            &lt;p&gt;We&#8217;re kind-hearted people here at OGC. Sometimes we take in strays. Rick can tell you about his dog if you ask, and I&#8217;ve fostered more cats than I care to deal with again (3 or thereabouts). So when our neighborly friend &lt;a href=&quot;http://www.jeremymcanally.com/&quot;&gt;Mr. Jeremy McAnally&lt;/a&gt; heard that &lt;a href=&quot;http://www.erebor.com/2009/01/03/learning-to-pair-program/&quot;&gt;his buddy Ryan wanted to try his hand at a Corey Haines-esque pairing tour&lt;/a&gt;, he naturally thought of &lt;del&gt;foisting Ryan off on&lt;/del&gt; &lt;ins&gt;recommending him to&lt;/ins&gt; us.&lt;/p&gt;

&lt;p&gt;After some e-mail back-and-forth, we settled on a date for Ryan to come up and spend a day in the OGC lair. It kind of sucked because it made me get up and out of the house and seeing my esteemed partners and colleagues earlier than my norm, and it was also the day I finally killed my car, but other than that it was a very good day. Ryan has &lt;a href=&quot;http://www.erebor.com/2009/01/16/telling-stories-in-nashville/&quot;&gt;his take of the day&#8217;s events&lt;/a&gt; up, but I thought I&#8217;d try to put forth my own.&lt;/p&gt;

&lt;p&gt;We met at Kevin&#8217;s a little early to talk over some final ideas while waiting on Ryan to show up, as he promptly did at our agreed-upon time of 10am. Then we went over the overview of what we&#8217;d be working on, including a bit of history of the people involved, where our data model came from, why we&#8217;re focusing on one particular part of the app to start it up. From there, we looked at the stories we&#8217;d collected, split into two pairs (I got Ryan to start), and got to work.&lt;/p&gt;

&lt;p&gt;It may have felt to Ryan like he was slowing me down, but as I explained to him, sometimes being slowed down is a good thing. In my mind, one of the primary benefits of practices like writing stories, BDD, and pairing is that they slow you down and make you think about what you&#8217;re doing. They give you the time to design and code better. Paradoxironically, they speed you up by slowing you down.&lt;/p&gt;

&lt;p&gt;And all the stuff he said he learned, I told him that our first 3-2-1 taught us much of the same. Just watching someone else with different practices, different knowledge, different ideas &amp;mdash; there&#8217;s so much you can pick up. Actually getting to &lt;em&gt;work with&lt;/em&gt; a person like that? Forget about it. And packing that into an intense day (or few) instead of just making it an every-now-and-then thing? Oh man.&lt;/p&gt;

&lt;p&gt;As a three-man team, we have some mathematic disadvantage when it comes to constant and vigilant pairing. We also have other interests and personal lives that have us in a fairly common situation of developing separately but together, off in our own coding worlds with communication through various electronic means. It doesn&#8217;t have the same benefits of in-person pairing, as we&#8217;re reminded when we do get together and smack down a bunch of stories while talking to each other. It&#8217;s nice to carve out time and get into that groove.&lt;/p&gt;

&lt;p&gt;Anyone else want a piece of this? Come on up. We&#8217;d like to have you. Just keep in mind that Ryan&#8217;s set a precedent of the guest paying for lunch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; They say good news travels fast. Two local programmers have contacted us about pairing opportunities. Also, we&#8217;re working on a follow-up pairing session with Ryan in the next month or two. That, or he wants to kidnap my dog! &lt;em&gt;&#8211;Kevin&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-11-10:507</id>
    <published>2008-11-10T15:51:00Z</published>
    <updated>2008-11-30T17:00:07Z</updated>
    <link href="http://b.logi.cx/2008/11/10/rubyconf-with-extra-epcot-action" rel="alternate" type="text/html"/>
    <title>RubyConf, with extra Epcot action</title>
<content type="html">
            &lt;p&gt;Another RubyConf has come and gone, and nothing really makes a conference special like driving over 10 hours in each direction. That wasn&#8217;t my specific experience because I had some other engagements that turned the trip into a Houston/Austin/Orlando flying junket, but the other two guys can tell you all about it. The drive back started with breakfast at the most amazing McDonald&#8217;s we&#8217;ve ever seen, possibly the most amazing in existence. It&#8217;s a shame we didn&#8217;t think to get proof of the crazy.&lt;/p&gt;

&lt;p&gt;But there&#8217;s more to a conference than the travel, like staying at a resort hotel with a lazy river. And drinking beer while having testing-related conversations with wonderful members of the community. And racing go karts.&lt;/p&gt;

&lt;p&gt;There were also talks, of course. I was on the roster as part of the &lt;a href=&quot;http://rubyconf.org/talks/83&quot;&gt;&#8220;Two Turntables and a Git Repo&#8221;&lt;/a&gt; talk, which went swimmingly. &lt;a href=&quot;http://bleything.net/&quot;&gt;Mr. Ben Bleything&lt;/a&gt; and I apparently know how to please a crowd, and I like to think maybe they actually learned something as well. This time I&#8217;m not going to bother putting up my slides on slideshare because they don&#8217;t make a lot of sense without me and without the music. &lt;a href=&quot;http://www.confreaks.com/&quot;&gt;Confreaks&lt;/a&gt; were there, so &lt;a href=&quot;http://rubyconf2008.confreaks.com/two-turntables-and-a-git-repo.html&quot;&gt;the video&lt;/a&gt; will do the subject more justice.&lt;/p&gt;

&lt;p&gt;Anyway, you really want to see &lt;a href=&quot;http://rubyconf2008.confreaks.com/how-i-learned-to-love-javascript.html&quot;&gt;the video&lt;/a&gt; of Aaron Patterson and John Barnette presenting about &lt;a href=&quot;http://tenderlovemaking.com/2008/04/23/take-it-to-the-limit-one-more-time/&quot;&gt;Johnson&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>vinbarnes</name>
    </author>
    <id>tag:b.logi.cx,2008-10-23:470</id>
    <published>2008-10-23T14:34:00Z</published>
    <updated>2008-10-23T14:35:12Z</updated>
    <link href="http://b.logi.cx/2008/10/23/agile-elsewhere-github-inline-editing" rel="alternate" type="text/html"/>
    <title>Agile Elsewhere: github inline editing</title>
<content type="html">
            &lt;p&gt;If I recall, this &lt;a href=&quot;http://github.com/blog/143-inline-file-editing&quot;&gt;feature&lt;/a&gt; was released back in August so I'm a little late in heaping my praise gravy on the Thanksgiving turkey that is the github crew. But this is the first time I had the need to use it. I noticed some formatting for the README.rdoc in my project was b0rked.&lt;/p&gt;

&lt;img src=&quot;http://img.skitch.com/20080819-r4d7gdi5129e7yyg5b9xr2p4cs.png&quot; /&gt;

&lt;p&gt;I clicked the little &lt;tt&gt;edit&lt;/tt&gt; link. Made my changes. Added a commit message. Hit the Commit button. Voila! And all on one page. Easy as cake!&lt;/p&gt;

&lt;p&gt;Talk about agile!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>rickbradley</name>
    </author>
    <id>tag:b.logi.cx,2008-10-21:456</id>
    <published>2008-10-21T16:41:00Z</published>
    <updated>2008-10-21T16:41:59Z</updated>
    <category term="bill"/>
    <category term="disenfranchisement"/>
    <category term="dollar"/>
    <category term="fascism"/>
    <category term="ogc"/>
    <category term="schwag"/>
    <category term="yall"/>
    <link href="http://b.logi.cx/2008/10/21/ogc-electioneering-adds-yard-signs" rel="alternate" type="text/html"/>
    <title>OGC electioneering adds yard signs!</title>
<content type="html">
            &lt;p&gt;Ready for the election to be over?  Enlightened about your once and future disenfranchisement?  Need more fun than getting cranked up on Olde English and driving over the McBama signs in your neighbors&#8217; yards?&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;OGC&lt;/span&gt;, as always, is here to help.&lt;/p&gt;


	&lt;p&gt;Exercise your First Amendment rights as a fifth-year senior in the elecotral college with our brand-spankin&#8217;-new &#8220;I&#8217;ll Vote When I&#8217;m Dead&#8221; &lt;a href=&quot;http://www.cafepress.com/flogicx.319785921&quot;&gt;Yard Signs&lt;/a&gt;:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://images.cafepress.com/product/319785921v2_350x350_Front.jpg&quot;&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.cafepress.com/flogicx.319785921&quot;&gt;Get &#8216;em now!&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;And remember:  the bottom of the boot always looks the same!&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://paulitics.files.wordpress.com/2007/07/fascism_not_us_1.jpg&quot;&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-10-20:451</id>
    <published>2008-10-20T18:05:00Z</published>
    <updated>2008-10-20T18:09:27Z</updated>
    <link href="http://b.logi.cx/2008/10/20/orlando-or-close-enough-or-bust" rel="alternate" type="text/html"/>
    <title>Orlando (or close enough) or bust</title>
<content type="html">
            &lt;p&gt;The OGs will be out in force at RubyConf 2008 in sunny near-Orlando, Florida. Kevin and Rick will be attending, hacking, heckling, and possibly giving away fabulous prizes. Yossef (that&#8217;s me) will be giving a talk along with Mr. &lt;a href=&quot;http://bleything.net/&quot;&gt;Ben Bleything&lt;/a&gt; and the inimitable (I&#8217;d like to see you try) &lt;a href=&quot;http://gilesbowkett.blogspot.com/&quot;&gt;Giles Bowkett&lt;/a&gt; about &lt;a href=&quot;http://rubyconf.org/talks/83&quot;&gt;music generation and manipulation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Come see us. We&#8217;ll chat. Maybe we&#8217;ll get you a beer.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-10-09:389</id>
    <published>2008-10-09T02:45:00Z</published>
    <updated>2008-10-22T19:04:07Z</updated>
    <link href="http://b.logi.cx/2008/10/9/non-auto-spec" rel="alternate" type="text/html"/>
    <title>non-auto spec</title>
<content type="html">
            &lt;p&gt;I've been resisting updating a few gems because I either don't want the changes or simply don't know what to think about them. Today, however, I decided to get up-to-date on almost everything, and so I went for RSpec 1.1.8. Before this, I was running 1.1.4, and the change I was unsure about involved the &lt;code&gt;autospec&lt;/code&gt; command. From the changelog:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;IMPORTANT: use ‘script/autospec’ (or just ‘autospec’ if you have the rspec gem installed) instead of ‘autotest’. We changed the way autotest discovers rspec so the autotest executable won‘t automatically load rspec anymore. This allows rspec to live side by side other spec frameworks without always co-opting autotest through autotest‘s discovery mechanism.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I ignore this at first because that's just the way I am, and no tests are run. So I try &lt;code&gt;autospec&lt;/code&gt;, and still no tests are run. I managed to track it down to an addition from Rick that's pretty helpful with large projects. Simply add this to your &lt;code&gt;.autotest&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Autotest.send(:alias_method, :real_find_files, :find_files)
Autotest.send(:define_method, :find_files) do |*args|
  pattern = ENV['AUTOTEST']
  files = real_find_files
  if pattern and !pattern.empty?
    files = files.reject { |k, v|  !Regexp.new(pattern).match(k) }
  end
  files
end&lt;/pre&gt;&lt;/code&gt;
&lt;small&gt;(note the use of &lt;code&gt;Hash#reject&lt;/code&gt; because &lt;code&gt;Hash#select&lt;/code&gt; is stupid)&lt;/small&gt;
&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;
and then, to make things even easier, define an alias (or function)&lt;/p&gt;

&lt;p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;ta() {
  AUTOTEST=${1:-.} autotest
}&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It turns out that for some reason, autospec sets &lt;code&gt;ENV['AUTOTEST']&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. So I changed it to use a different name, and still no tests were running, but this time I see files in the command line.&lt;/p&gt;

&lt;p&gt;Then I take a closer look.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -S spec/spec_helper.rb spec/playlist_spec.rb spec/pj_spec.rb spec/track_spec.rb -O spec/spec.opts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;spec/spec_helper.rb&lt;/code&gt;, you say? That's interesting. Before the upgrade, it was different.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -S /Library/Ruby/Gems/1.8/gems/rspec-1.1.4/bin/spec -O spec/spec.opts  spec/playlist_spec.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Right now I'm looking at upgrading to a working version of RSpec, like 1.1.4.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Update (22 Oct 2008): RSpec 1.1.9 fixes the problem (by trying to run the specs and not &lt;code&gt;spec/spec_helper.rb&lt;/code&gt;). Happy times.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-08-28:239</id>
    <published>2008-08-28T17:00:00Z</published>
    <updated>2008-11-02T22:34:26Z</updated>
    <category term="&quot;test all the fucking time&quot;"/>
    <category term="matcher"/>
    <category term="rspec"/>
    <link href="http://b.logi.cx/2008/8/28/tests-all-the-way-down" rel="alternate" type="text/html"/>
    <title>Tests all the way down</title>
<summary type="html">&lt;p&gt;UPDATE:  An updated gist of the code in this article can be found &lt;a href=&quot;http://gist.github.com/21755&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A recent project had us using ThinkingSphinx for the first time. We've done some with UltraSphinx, but we were open to new ideas. And ReinH was (at least tangentionally) involved, so we bowed to the heavy weight of authority that comes from writing &lt;a href=&quot;http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx.html&quot;&gt;a blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I admit that defining indexes in ThinkingSphinx is nicer than UltraSphinx, but there are &lt;code&gt;method_missing&lt;/code&gt; and state-keeping tricks that give me pause. For me, though, it all comes down to writing the spec. Being BDD-infected as we are, writing code without specs hurts. It's simple to say that a column is indexed&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class User &amp;lt; ActiveRecord::Base
  define_index do
    indexes email
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But how to write the failing test that passes when that code is put in?&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;UPDATE:  An updated gist of the code in this article can be found &lt;a href=&quot;http://gist.github.com/21755&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A recent project had us using ThinkingSphinx for the first time. We've done some with UltraSphinx, but we were open to new ideas. And ReinH was (at least tangentionally) involved, so we bowed to the heavy weight of authority that comes from writing &lt;a href=&quot;http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx.html&quot;&gt;a blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I admit that defining indexes in ThinkingSphinx is nicer than UltraSphinx, but there are &lt;code&gt;method_missing&lt;/code&gt; and state-keeping tricks that give me pause. For me, though, it all comes down to writing the spec. Being BDD-infected as we are, writing code without specs hurts. It's simple to say that a column is indexed&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class User &amp;lt; ActiveRecord::Base
  define_index do
    indexes email
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But how to write the failing test that passes when that code is put in?&lt;/p&gt;
&lt;p&gt;(As an aside, we know that this sort of test is punting on the real problem. I'd like to see the behavior in action rather than just query the class to see if it has indexes. That's what I do with validations, but with searching it becomes a full-scale integration test involving a search server and too much pain to manage, so we punt. For the record, we asked around and apparently Evan Weaver is the only one who does that kind of integration testing. I figure it's kind of telling that only one person tests it that way, and it's the author of UltraSphinx.)&lt;/p&gt;

&lt;p&gt;A spike showed us the way. It was a bit of a pain to traverse the maze of index information, and those &lt;code&gt;method_missing&lt;/code&gt; tricks pained me. I don't have that console session to recreate here, but this is the final result:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;User.indexes.collect(&amp;amp;:fields).flatten.collect(&amp;:columns).flatten.collect(&amp;:__name).include?(:email)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, one could say this convoluted access to indexing information means ThinkingSphinx wasn't written spec-first. I'm here to point out that BDD isn't a panacea. All BDD does is prove that the code matches the spec. As such there's always the looming specter of unspecified behavior, and of course nothing can save you when you've written the wrong specs.&lt;/p&gt;

&lt;p&gt;Some time ago, we found a blog post called &lt;a href=&quot;http://tuples.us/2007/10/23/if-you-arent-writing-matchers-you-arent-using-rspec/&quot;&gt;&quot;If you aren't writing Matchers, you aren't using RSpec&quot;&lt;/a&gt;, and at the time I discounted it. Mostly I figure if the test looks like butt, I change the code to be easier to test. This situation was different for two reasons: 1) the code wasn't mine to change, and A) it was a severe time-crunch situation. So Rick and I paired on writing a matcher for this thing. And it worked. We referred to the article a few times since it was so informative. There was one glaring omission, though. There was a complete lack of tests.&lt;/p&gt;

&lt;p&gt;Remember what I said about being BDD-infected? It's no joke. And I think the things you depend on in your tests need to be tested the best. They're a foundation of your entire testing structure. Would you want to build a house on quicksand? Now, this was test-after because we followed the article to write the matcher, but I still think the tests are nothing to sneeze at.&lt;/p&gt;

&lt;p&gt;The matcher code (which went into spec/custom_matchers.rb):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ThinkingSphinxIndexMatcher
  class HaveIndex
    def initialize(expected)
      @expected = expected
    end

    def matches?(target)
      @target = target
      target.indexes.collect(&amp;:fields).flatten.collect(&amp;:columns).flatten.collect(&amp;:__name).include?(@expected)
    end

    def failure_message
      &quot;expected #{@target} to index #{@expected}&quot;
    end

    def negative_failure_message
      &quot;expected #{@target} not to index #{@expected}, but did&quot;
    end
  end

  def have_index(expected)
    HaveIndex.new(expected)
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The spec (which was in sanity/have_index_matcher_spec.rb):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require File.dirname(__FILE__) + '/../spec_helper'

describe ThinkingSphinxIndexMatcher::HaveIndex do
  before :each do
    @expected = 'some val'
    @target   = 'some tgt'
    @matcher  = ThinkingSphinxIndexMatcher::HaveIndex.new(@expected)
  end

  describe 'when initialized' do
    it 'should accept an expected value' do
      lambda { ThinkingSphinxIndexMatcher::HaveIndex.new(@expected) }.should_not raise_error(ArgumentError)
    end

    it 'should require an expected value' do
      lambda { ThinkingSphinxIndexMatcher::HaveIndex.new }.should raise_error(ArgumentError)
    end

    it 'should store the expected value' do
      ThinkingSphinxIndexMatcher::HaveIndex.new(@expected).instance_variable_get('@expected').should == @expected
    end
  end

  it 'should have a failure message' do
    @matcher.should respond_to(:failure_message)
  end

  describe 'failure message' do
    before :each do
      @matcher.instance_variable_set('@target', @target)
    end

    it 'should explain the problem, containing the target and expected value' do
      @matcher.failure_message.should == 'expected some tgt to index some val'
    end
  end

  it 'should have a negative failure message' do
    @matcher.should respond_to(:negative_failure_message)
  end

  describe 'negative failure message' do
    before :each do
      @matcher.instance_variable_set('@target', @target)
    end

    it 'should explain the problem, containing the target and expected value' do
      @matcher.negative_failure_message.should == 'expected some tgt not to index some val, but did'
    end
  end

  it 'should tell if a target matches the expectation' do
    @matcher.should respond_to(:matches?)
  end

  describe 'telling if a target matches the expectation' do
    before :each do
      @target.stubs(:indexes).returns([])
    end

    it 'should accept a target' do
      lambda { @matcher.matches?(@target) }.should_not raise_error(ArgumentError)
    end

    it 'should require a target' do
      lambda { @matcher.matches? }.should raise_error(ArgumentError)
    end

    it 'should set the target' do
      @matcher.matches?(@target)
      @matcher.instance_variable_get('@target').should == @target
    end

    it &quot;should go through the target's indexes&quot; do
      @target.expects(:indexes).returns([])
      @matcher.matches?(@target)
    end

    describe 'when the target has no indexes' do
      before :each do
        @target.stubs(:indexes).returns([])
      end

      it 'should return a false value' do
        result = @matcher.matches?(@target)
        (!!result).should == false
      end
    end

    describe 'when the target has indexes' do
      describe 'and an index includes the expected value' do
        before :each do
          indexes = [
            stub('index', :fields =&gt; []),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [])]),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [stub('column', :__name =&gt; 'blah')])]),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [stub('column', :__name =&gt; @expected)])]),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [stub('column', :__name =&gt; 'other'), stub('column', :__name =&gt; 'feh')])])
          ]
          @target.stubs(:indexes).returns(indexes)
        end

        it 'should return a true value' do
          result = @matcher.matches?(@target)
          (!!result).should == true
        end
      end

      describe 'and no index includes the expected value' do
        before :each do
          indexes = [
            stub('index', :fields =&gt; []),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [])]),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [stub('column', :__name =&gt; 'blah')])]),
            stub('index', :fields =&gt; [stub('field', :columns =&gt; [stub('column', :__name =&gt; 'other'), stub('column', :__name =&gt; 'feh')])])
          ]
          @target.stubs(:indexes).returns(indexes)
        end

        it 'should return a false value' do
          result = @matcher.matches?(@target)
          (!!result).should == false
        end
      end
    end
  end
end

describe ThinkingSphinxIndexMatcher do
  before :each do
    @expected = 'some val'
    @helper = Object.new
    @helper.extend(ThinkingSphinxIndexMatcher)
    @matcher = stub('matcher')
    ThinkingSphinxIndexMatcher::HaveIndex.stubs(:new).returns(@matcher)
  end

  it &quot;should provide a 'have_index' method&quot; do
    @helper.should respond_to(:have_index)
  end

  describe &quot;'have_index' method&quot; do
    it 'should accept an expected value' do
      lambda { @helper.have_index(@expected) }.should_not raise_error(ArgumentError)
    end

    it 'should require an expected value' do
      lambda { @helper.have_index }.should raise_error(ArgumentError)
    end

    it 'should create a matcher for the expected value' do
      ThinkingSphinxIndexMatcher::HaveIndex.expects(:new).with(@expected)
      @helper.have_index(@expected)
    end

    it 'should return the matcher' do
      @helper.have_index(@expected).should == @matcher
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The addition to spec_helper:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require File.expand_path(File.dirname(__FILE__) + '/custom_matchers')

Spec::Runner.configure do |config|
  config.include ThinkingSphinxIndexMatcher
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(These are all available at &lt;a href=&quot;http://gist.github.com/7765&quot;&gt;gist #7765&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Note that I never made a spec to test that have_index is available in the specs. Mea culpa, folks. I wasn't sure where those methods go and did I mention the time crunch? I think it would be easier if &lt;code&gt;should&lt;/code&gt; returned an object that had methods directly called on it so things like &lt;code&gt;respond_to&lt;/code&gt; and &lt;code&gt;include&lt;/code&gt; weren't shoved into the wrong place. Remember the good ol' days when RSpec looked like &lt;code&gt;object.should.be_nil&lt;/code&gt;? Apparently that was too ugly to keep.&lt;/p&gt;

&lt;p&gt;All in all, this was something of an adventure. As I told Rein, when it comes to learning how something works, there's nothing quite like trying to figure out how in the hell to test it.&lt;/p&gt;

&lt;p&gt;Oh, and in the end the spec looks like&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe User do
  describe 'as a class' do
    it 'should be searchable' do
      User.should respond_to(:search)
    end

    it 'should allow searching by email address' do
      User.should have_index(:email)
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-08-25:224</id>
    <published>2008-08-25T20:47:00Z</published>
    <updated>2008-08-25T20:48:28Z</updated>
    <link href="http://b.logi.cx/2008/8/25/fight-on-fight-on-for-ol-jax-state" rel="alternate" type="text/html"/>
    <title>Fight on, fight on for ol' Jax State</title>
<content type="html">
            &lt;p&gt;That&#8217;s about a Jacksonville in a different state, but how can you resist any song containing the lyric &#8220;We&#8217;re proud that we&#8217;re from Alabama!&#8221;?&lt;/p&gt;

&lt;p&gt;Maybe I&#8217;d be more impressed if the author bothered to rhyme it.&lt;/p&gt;

&lt;p&gt;The boys of OG Consulting have returned to their homeland from another &lt;a href=&quot;http://www.hashrocket.com/products&quot;&gt;3-2-1&lt;/a&gt; excursion into &lt;a href=&quot;http://www.hashrocket.com/&quot;&gt;Hashrocket&lt;/a&gt; territory. &lt;a href=&quot;http://b.logi.cx/2008/7/20/all-together-on-three&quot;&gt;Posting about the previous time&lt;/a&gt; gave a look into the 3-2-1 experience. This time was similar, yet not exactly; different, yet not hugely so. There were some problems that came up in the post-mortem last time, and those were largely taken care of. Of course, we had different problems this time (isn&#8217;t that always the way?), and we tried to address those as quickly as possible in a mid-mortem instead of waiting until the effort was over. &lt;/p&gt;

&lt;p&gt;And on top of that we had a big ol&#8217; storm harassing us. I whipped up an image to give a feel for that adventure.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://b.logi.cx/assets/2008/8/25/fay_hits_florida.png&quot;&gt;&lt;img src=&quot;http://b.logi.cx/assets/2008/8/25/fay_hits_florida.png&quot; height=&quot;240&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It looked like planning for an extra weekend on the beach and bringing bathing suits was going to end up a waste, but Fay passed us on Friday and we were able to enjoy Saturday outside. Rick and I have the sunburns to show for it.&lt;/p&gt;

&lt;p&gt;Shout-outs this time to everyone mentioned in the last post, of course, and also &lt;a href=&quot;http://turriate.com/&quot;&gt;Sandro&lt;/a&gt;, &lt;a href=&quot;http://www.carmelyne.com/&quot;&gt;Carmelyne&lt;/a&gt;, Les, Wes, Esther, Lark, Alex, Corey, and Dan. And of course a special shout-out to Mark for putting us up again in that sweet condo. Three bedrooms, three guest stars, three members of OG Consulting. Maybe a third 3-2-1 is called for.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-08-13:161</id>
    <published>2008-08-13T16:56:00Z</published>
    <updated>2008-08-14T17:51:56Z</updated>
    <link href="http://b.logi.cx/2008/8/13/ruby-1-9-shmuby-1-sh9" rel="alternate" type="text/html"/>
    <title>Ruby 1.9, Shmuby 1.sh9</title>
<summary type="html">&lt;p&gt;There&#8217;s a lot of buzz about Ruby 1.9, at least if you&#8217;re looking in the right places. Sam Ruby gave a &lt;a href=&quot;http://intertwingly.net/blog/2008/07/24/Ruby-1-9-What-to-Expect&quot;&gt;presentation about what to expect&lt;/a&gt; at OSCON, and I just found the slides today. They have me seeing red.&lt;/p&gt;

&lt;p&gt;Before anyone gets the wrong idea, that&#8217;s not all aimed at Sam. It&#8217;s not even mostly aimed at Sam. I know it&#8217;s hard to put a good presentation together, and like anything else, the mistakes that are obvious after the fact were hiding during all the preparations and preliminary run-throughs.&lt;/p&gt;

&lt;p&gt;So, some &amp;hellip; let&#8217;s say &#8220;observations&#8221; about the slides.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;There&#8217;s a lot of buzz about Ruby 1.9, at least if you&#8217;re looking in the right places. Sam Ruby gave a &lt;a href=&quot;http://intertwingly.net/blog/2008/07/24/Ruby-1-9-What-to-Expect&quot;&gt;presentation about what to expect&lt;/a&gt; at OSCON, and I just found the slides today. They have me seeing red.&lt;/p&gt;

&lt;p&gt;Before anyone gets the wrong idea, that&#8217;s not all aimed at Sam. It&#8217;s not even mostly aimed at Sam. I know it&#8217;s hard to put a good presentation together, and like anything else, the mistakes that are obvious after the fact were hiding during all the preparations and preliminary run-throughs.&lt;/p&gt;

&lt;p&gt;So, some &amp;hellip; let&#8217;s say &#8220;observations&#8221; about the slides.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;(Note that I don&#8217;t have Ruby 1.9 installed and don&#8217;t plan to do anything with it or anything else past 1.8.6, not just yet.)&lt;/small&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;code&gt;?&lt;/code&gt; (used like &lt;code&gt;?c&lt;/code&gt;), like &lt;code&gt;defined?&lt;/code&gt;, was something of an annoyance (or it would have been had I ever wanted to use it). The shock of being suddenly shoved into a different world where normal scoping rules don&#8217;t apply is too much. And now that &lt;code&gt;?c&lt;/code&gt; will return &lt;code&gt;'c'&lt;/code&gt; instead of &lt;code&gt;99&lt;/code&gt;, what&#8217;s the way to get the ASCII value? Is there &lt;code&gt;String#ord&lt;/code&gt;? Not that it ever really concerned me since I&#8217;m actually trying to write Ruby and not C, but it seems like some people care. For instance, I think Ryan Davis used &lt;code&gt;?&lt;/code&gt; heavily, so I can take some consolation in the fact that 1.9 will break some of his code.&lt;/p&gt;

&lt;p&gt;The example given for &lt;code&gt;Array#to_s&lt;/code&gt; makes it look like &lt;code&gt;Array#inspect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apparently there was a lot of debate about the slide showing &lt;code&gt;[1,2,3].each { |i| ... }&lt;/code&gt; vs. &lt;code&gt;for i in [1,2,3]&lt;/code&gt;. My humble suggestion is that anyone liking the &lt;code&gt;for i in&lt;/code&gt; syntax should go back to PHP.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Fixnum#to_sym&lt;/code&gt; presently returns &lt;code&gt;nil&lt;/code&gt;? Who knew?&lt;/p&gt;

&lt;p&gt;He already has errata for the &#8216;Hash Keys Now Unordered&#8217; slide.&lt;/p&gt;

&lt;p&gt;Okay, the &lt;code&gt;BasicObject&lt;/code&gt; slide just hurt my head. This doesn&#8217;t even show what I would expect to see, which is that &lt;code&gt;BasicObject&lt;/code&gt; has even fewer methods than &lt;code&gt;BlankSlate&lt;/code&gt; (a &lt;code&gt;NoneMoreBlankSlate&lt;/code&gt;, if you will). Instead, it shows something that looks like constant lookup being hijacked, detoured, and driven into a cliff.&lt;/p&gt;

&lt;p&gt;&#8220;The biggest obstacle to Ruby 1.9’s adoption is the sheer number of mostly working but essentially unmaintained gems that virtually everybody in the Ruby community depends on.&#8221; &lt;em&gt;ahem&lt;/em&gt; You know who you are.&lt;/p&gt;

&lt;p&gt;Nitpick: For the alternate Hash syntax, the example should have &#8216;show&#8217; quoted/&lt;/p&gt;

&lt;p&gt;Jesus, who doesn&#8217;t hate stabby proc? And this also includes one of my pet peeves: defining a arg-taking method without using parentheses.&lt;/p&gt;

&lt;p&gt;He implies that 1.8.6 doesn&#8217;t allow lambdas to be called with &lt;code&gt;[]&lt;/code&gt;. And 1.9 allows a lambda to be called like &lt;code&gt;x.(1,2,3)&lt;/code&gt;? C&#8217;mon, people.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Complex(3,4) == 3 + 4.im&lt;/code&gt;. Not &lt;code&gt;4.i&lt;/code&gt;? Painful.&lt;/p&gt;

&lt;p&gt;It took me far too long to even read the stabby proc line of the &#8216;Splat in Middle&#8217; slide. I&#8217;ve never read &lt;cite&gt;Structure and Interpretation of Computer Programs&lt;/cite&gt;, but I know that &#8220;Programs should be written for people to read, and only incidentally for machines to execute.&#8221;&lt;/p&gt;

&lt;p&gt;He already has errata for the &#8216;&#8220;Nested&#8221; Methods&#8217; slide.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;br /&gt;
That&#8217;s all I have now. I have to go lie down and take some deep breaths.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-08-11:152</id>
    <published>2008-08-11T14:50:00Z</published>
    <updated>2008-08-29T16:26:59Z</updated>
    <category term="conference"/>
    <category term="hoedown"/>
    <category term="ruby"/>
    <link href="http://b.logi.cx/2008/8/11/down-home-hoedown-action" rel="alternate" type="text/html"/>
    <title>Down-home Hoedown action</title>
<content type="html">
            &lt;p&gt;We were in Hunstville for the &lt;a href=&quot;http://www.rubyhoedown.com/&quot;&gt;Ruby Hoedown&lt;/a&gt; this past weekend, and let me just say that Jeremy McAnally knows how to put on a hoedown. All you people who didn&#8217;t come because of the location or the size or the timing or any other reason, you screwed up.&lt;/p&gt;

&lt;p&gt;With two EVDO cards and a nice AP, &lt;a href=&quot;http://confreaks.org/&quot;&gt;Confreaks&lt;/a&gt; managed to give one of the best conference networks I&#8217;ve ever experienced. Granted, I don&#8217;t have a lot of conference experience, but I know enough to say Confreaks &lt;a href=&quot;http://en.wikipedia.org/wiki/Inequality&quot;&gt;&amp;raquo;&lt;/a&gt; O&#8217;Reilly. I think in general this was the best conference experience I&#8217;ve had, owing in large part to the regional aspects: smaller, more focused (as in there was only one track), less focused (schedule not completely nailed down, good hallway track action).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/obie/2750731456&quot;&gt;&lt;img src=&quot;http://b.logi.cx/assets/2008/8/11/2750731456_95a4c0e43d.jpg&quot; height=&quot;166&quot; width=&quot;250&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Obie catches us in a moment, probably thinking of ways to screw with Rein during his talk&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Rick, being on the schedule, gave his talk on going through a major refactoring and adding tests to old code, focusing on the experience of turning &lt;a href=&quot;http://ruby.sadi.st/Flog.html&quot;&gt;flog&lt;/a&gt; into &lt;a href=&quot;http://github.com/flogic/flame&quot;&gt;flame&lt;/a&gt;. I was inspired to give a lightning talk on &lt;a href=&quot;http://github.com/ymendel/truthy&quot;&gt;truthy&lt;/a&gt;. Kevin managed to squeeze one day of the Hoedown in between other blocks on his busy schedule &amp;mdash; legitimizing us with the presence of an iPhone &amp;mdash; so this wasn&#8217;t the conference to get &#8220;the full OG monty&#8221;, as it were. Maybe we&#8217;ll have to break open the seal on that at something even more local than a regional conference. NashDL OGConf, anyone?&lt;/p&gt;

&lt;p&gt;Other highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hashrocket quoting me in their 3-2-1 ad on the back of the schedule&lt;/li&gt;
&lt;li&gt;Obie including our logo among many others, showing the consultancy marketplace in his &lt;a href=&quot;http://rubyhoedown2008.confreaks.com/07-obie-fernandez-do-the-hustle.html&quot;&gt;&#8220;Hustle&#8221; presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Getting a dollar from Joe Kutner for explaining why &lt;code&gt;!=&lt;/code&gt; isn&#8217;t a method&lt;/li&gt;
&lt;li&gt;Finally seeing Giles (&lt;a href=&quot;http://en.wikipedia.org/wiki/The_Takahashi_method&quot;&gt;&#8220;Crakahashi Method&#8221;&lt;/a&gt;) Bowkett present&lt;/li&gt;
&lt;li&gt;Being disqualified from the &lt;a href=&quot;http://en.wikipedia.org/wiki/Rock_paper_scissors&quot;&gt;RPS&lt;/a&gt;bot competition for cheating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was a good time. What do you expect when testing, pizza, and bocce come together?&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Rick&#8217;s talk on flog/flame: (get &lt;a href=&quot;http://rickbradley.com/misc/ﬂog-snapshot.tar.gz&quot;&gt;the code to follow along&lt;/a&gt;)&lt;/p&gt;

&lt;div&gt;&lt;a href=&quot;http://www.slideshare.net/ogc/flog-testnew-551094?src=embed&quot; title=&quot;flog &amp;amp;lt;&amp;amp;lt; Test.new&quot;&gt;flog &amp;lt;&amp;lt; Test.new&lt;/a&gt;&amp;lt;object height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;embed src=&quot;http://static.slideshare.net/swf/ssplayer2.swf?doc=rubyhoedown2008-1218509498212447-9&amp;amp;stripped_title=flog-testnew-551094&quot; height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;div&gt;View SlideShare &lt;a href=&quot;http://www.slideshare.net/ogc/flog-testnew-551094?src=embed&quot; title=&quot;View flog &amp;amp;lt;&amp;amp;lt; Test.new on SlideShare&quot;&gt;presentation&lt;/a&gt; (tags: &lt;a href=&quot;http://slideshare.net/tag/rubyhoedown2008&quot;&gt;rubyhoedown2008&lt;/a&gt;)&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://rubyhoedown2008.confreaks.com/11-rick-bradley-flog-test-new.html&quot;&gt;Recorded by Confreaks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.viddler.com/explore/GreggPollack/videos/5/468.07/Rick%20Bradley&quot;&gt;Rick giving Gregg Pollack from RailsEnvy the overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My lightning talk on truthy:&lt;/p&gt;

&lt;div&gt;&lt;a href=&quot;http://www.slideshare.net/ogc/the-nature-of-truth?src=embed&quot; title=&quot;The Nature of Truth&quot;&gt;The Nature of Truth&lt;/a&gt;&amp;lt;object height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;embed src=&quot;http://static.slideshare.net/swf/ssplayer2.swf?doc=truthiness-1218508539826491-9&amp;amp;stripped_title=the-nature-of-truth&quot; height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;div&gt;View SlideShare &lt;a href=&quot;http://www.slideshare.net/ogc/the-nature-of-truth?src=embed&quot; title=&quot;View The Nature of Truth on SlideShare&quot;&gt;presentation&lt;/a&gt; (tags: &lt;a href=&quot;http://slideshare.net/tag/rubyhoedown2008&quot;&gt;rubyhoedown2008&lt;/a&gt;)&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://rubyhoedown2008.confreaks.com/06-yosef-mendelssohn-lightning-talk-the-nature-of-truth.html&quot;&gt;Recorded by Confreaks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.viddler.com/explore/GreggPollack/videos/5/212.21/Yossef%20Mendelssohn&quot;&gt;Me giving Gregg Pollack from RailsEnvy the overview&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>rickbradley</name>
    </author>
    <id>tag:b.logi.cx,2008-08-02:118</id>
    <published>2008-08-02T20:00:00Z</published>
    <updated>2009-04-09T23:41:57Z</updated>
    <category term="bitches"/>
    <category term="can"/>
    <category term="git"/>
    <category term="github"/>
    <category term="gitosis"/>
    <category term="how"/>
    <category term="hubs"/>
    <category term="ogc"/>
    <link href="http://b.logi.cx/2008/8/2/mirroring-to-github" rel="alternate" type="text/html"/>
    <title>How Can:  Sharing Your Codes to the Git Hubs?</title>
<content type="html">
            &lt;p&gt;These days it seems that everyone is on the &lt;a href=&quot;http://www.github.com/&quot;&gt;github&lt;/a&gt; tip &#8211; cloning like a shitty star wars prequel, forking and pulling like a lobster banquet.  With github&#8217;s success have come a few growing pains &#8211; GFS is evidently a rude ho, which means that sometimes you can&#8217;t always just take the bus and get there, metaphorically speaking.&lt;/p&gt;

&lt;p&gt;Since git doesn&#8217;t rely on a centralized repository, github occasionally going pensive like a French actress shouldn&#8217;t really cramp one&#8217;s style as far as development is concerned.  Just commit locally, &lt;a href=&quot;http://drnicwilliams.com/2008/06/18/what-is-gitjour-gemjour-starjour/&quot;&gt;gitjour&lt;/a&gt; with your friends, and when github is back up, &lt;code&gt;git push github master&lt;/code&gt;.  Badda bing.&lt;/p&gt;

&lt;p&gt;It could conceivably be a bit of a headache if you&#8217;re hoping to deploy servers with capistrano or vlad and you&#8217;re relying on one single service to be up whenever you want to deploy.  Since git is so decentralized, however, it seems only natural to just use that decentralization to our advantage and try to eliminate single points of failure.  Redundancy, bitches!&lt;/p&gt;

&lt;p&gt;So let&#8217;s talk about how &lt;a href=&quot;http://bl.ogtastic.com&quot;&gt;OGC&lt;/a&gt; rolls.&lt;/p&gt;

&lt;p&gt;&amp;lt;center&gt;
&lt;img src=&quot;http://img.skitch.com/20080802-jkcndnqte2h1fu5mm8j4jji4ij.png&quot; alt=&quot;sharing your codes to the githubs&quot; /&gt;
&amp;lt;/center&gt;&lt;/p&gt;

&lt;p&gt;We were hosting our own internal git repos on our own server before github was publicly available (well, to be fair it was &lt;a href=&quot;http://www.michaelchaney.com/&quot;&gt;Michael&#8217;s server&lt;/a&gt;, and we eventually broke the lock off the wallet and rented some &lt;a href=&quot;http://www.slicehost.com/&quot;&gt;slicehost action&lt;/a&gt;).  Once github came along we hopped on and started pushing our open source projects over there as well.  We were pushing to both repositories &#8220;by hand&#8221; for a while, meaning that we&#8217;d &lt;code&gt;git push origin master&lt;/code&gt; and then &lt;code&gt;git push github master&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;First off:  ass pain.  We could make some aliases or shell scripts, or maybe use &lt;a href=&quot;http://github.com/cv/git-utils/tree/master&quot;&gt;git push-all&lt;/a&gt;.  Meh.  Second off, this ain&#8217;t DRY &#8211; the opportunities for lost or mismatched codez on different servers are too-ubiquitous (&#8220;toobiquitous&#8221;, in fact) for my liking.  Third off, this is clearly an open rabbit hole.  Aren&#8217;t we obligated to climb into it?&lt;/p&gt;

&lt;p&gt;So we made a number of changes.  Among them, we started using &lt;a href=&quot;http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way&quot;&gt;gitosis&lt;/a&gt; to manage our repos (both public and private) on our slicehost.  Then we made some configuration changes so that, once a project is setup, pushing to our slicehost repository for a project will automatically force a push to our github repository for the project.  Sweet.&lt;/p&gt;

&lt;p&gt;So, now, mirroring is easy, though setup on a per-project basis is still a bit cumbersome.  We want to document what we&#8217;ve done, not because it&#8217;s beautiful (yet) but to get it out there and then improve it.  Oh, and (to drop the Royal &#8220;we&#8221;) because ymendel keeps bitching that I need to write this damned blog article.  &lt;em&gt;[waves to Yossef.]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here&#8217;s how we&#8217;re doing the mirroring&#8230;  In the discussion that follows there are three machines involved:  (1) a local workstation (or laptop, as the case actually is) where I&#8217;m doing development work, I&#8217;ll refer to it as &#8220;local&#8221;; (2) a git repository host under our control, which will be running gitosis, to which we push, and which then mirrors to github, called &#8220;internal&#8221;; and (3) github.com.  Suggestions for process improvement are very welcome as there are still a few too many moving parts involved in setting up new projects.&lt;/p&gt;

&lt;h3&gt;Initial Setup&lt;/h3&gt;

&lt;p&gt;To get things set up initially, get yourself a unixy/linuxy host where you can set up gitosis for hosting.  Slicehost, linode, some dude&#8217;s box, whatever.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up gitosis on this &#8220;internal&#8221; machine.  We have a user named &#8216;git&#8217; to run gitosis.  The repositories are in &lt;code&gt;~git/repositories&lt;/code&gt;.  I followed &lt;a href=&quot;http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way&quot;&gt;this article on gitosis&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure the internal repo user has an ssh key that can be used on github:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;internal:~$ ssh-keygen
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the public key (&lt;code&gt;~/.ssh/id_dsa.pub&lt;/code&gt;, for example) to your github account&#8217;s key list.  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Per-project Setup&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up a repository for your project on github.com.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up a repository for your project on your internal gitosis server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;local:~$ cd ~/git/gitosis-admin
local:~/git/gitosis-admin$ git pull origin master
local:~/git/gitosis-admin$ vim gitosis.conf   ## add the project
local:~/git/gitosis-admin$ git commit -a -v 
local:~/git/gitosis-admin$ git push origin master
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actually make the internal repository by doing a push to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    local:~/git/gitosis-admin$ cd ~/git/
    local:~/git$ mkdir foo
    local:~/git$ cd foo
    local:~/git/foo$ git init
    local:~/git/foo$ touch README
    local:~/git/foo$ git commit -a -m &quot;Initial repository push.&quot;            
    local:~/git/foo$ git remote add origin git@internal:foo.git
    local:~/git/foo$ git push origin master:refs/heads/master
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;UPDATE 2009-04-08&lt;/strong&gt;: This is the start of the no-longer-necessary section. Check out &lt;a href=&quot;http://bl.ogtastic.com/2009/4/9/mirroring-to-github-part-two&quot;&gt;the new hotness&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up a remote called &#8220;github&#8221; on the internal gitosis repo pointing to github (use your username instead of flogic, duh):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;internal:~git/repositories/foo.git$ git remote add github git@github.com:flogic/foo.git
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up a hook in the internal repository so that when your commits come in to your internal repository they will be pushed out to the corresponding github repository.  We used post-update, but post-receive should work as well (&lt;a href=&quot;http://www.cl.kernel.org/pub/software/scm/git-core/docs/v1.5.2.5/hooks.html&quot;&gt;discussion of the various hooks git understands&lt;/a&gt;).  Thanks to &lt;a href=&quot;http://blog.fallingsnow.net/&quot;&gt;Evan Phoenix&lt;/a&gt; for the kick-start to get this working:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, make this file executable by &quot;chmod +x post-update&quot;.


git-update-server-info


exec git push --mirror github &amp;gt;&amp;gt; ~/github.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure the new hook is runnable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;internal:~git/repositories/foo.git$ chmod +x hooks/post-update
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(One question I have is, is there a way to do this with gitosis that doesn&#8217;t involve logging in on the server to add the remote and setup the hook?)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE 2009-04-08&lt;/strong&gt;: This is the end of the no-longer-necessary section. Check out &lt;a href=&quot;http://bl.ogtastic.com/2009/4/9/mirroring-to-github-part-two&quot;&gt;the new hotness&lt;/a&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We still set two remotes in our git configs, in case we ever want to manually push straight to github &#8211; our server could go down too, y&#8217;know (again, substitute your github username for &#8220;flogic&#8221;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;local$ git remote add origin git@ogtastic.com:foo.git
local$ git remote add github git@github.com:flogic/foo.git


local$ git config --list | grep ^remote
remote.origin.url=git@ogtastic.com:foo.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
remote.github.url=git@github.com:flogic/foo.git
remote.github.fetch=+refs/heads/*:refs/remotes/origin/*
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push to the internal server &#8230; it should just magically show up on github:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;local:~/git/foo$ echo &quot;test&quot; &amp;gt; README
local:~/git/foo$ git commit -a -m &quot;testing mirrored push to github&quot;
local:~/git/foo$ git push origin master
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For troubleshooting, we adopted &lt;a href=&quot;http://blog.fallingsnow.net/&quot;&gt;Evan&#8217;s&lt;/a&gt; idea and have a log file in the home directory of our internal server&#8217;s git user.  The log file will show the output of attempting to &lt;code&gt;git push --mirror&lt;/code&gt; to github.&lt;/p&gt;

&lt;p&gt;Anyway, happy codes sharings!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://b.logi.cx/">
    <author>
      <name>ymendel</name>
    </author>
    <id>tag:b.logi.cx,2008-07-23:119</id>
    <published>2008-07-23T17:14:00Z</published>
    <updated>2008-08-05T15:58:46Z</updated>
    <link href="http://b.logi.cx/2008/7/23/the-right-way-to-do-something-you-should-never-do" rel="alternate" type="text/html"/>
    <title>The right way to do something you should never do</title>
<content type="html">
            &lt;p&gt;One project we&#8217;re on now involves a dashboard view that has a continually updating list of items. This seemed like a perfect place to use &lt;a href=&quot;http://juggernaut.rubyforge.org/&quot;&gt;Juggernaut&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Like with anything else, there was the YAGNI discussion. This could happen with polling and regular AJAX, right? It turns out that not only is pushing with something like Juggernaut more lightweight than polling, it&#8217;s easier. There&#8217;s no need to contact the server and say &#8220;hey, give me everything after this&#8221; if you can get an update upon creation. &lt;/p&gt;

&lt;p&gt;The trouble is that anything involving Juggernaut seems to smack of MVC violation. It&#8217;s obvious that updating a list of items as they come in points to an observer with an &lt;code&gt;after_create&lt;/code&gt; callback, but using Juggernaut involves creating some JavaScript by hand or using one of the helpful render calls. So I need a controller. In a model. (Or a model-like thing.)&lt;/p&gt;

&lt;p&gt;In accordance with my M.O., I dove into the Rails code and promptly started cursing. Rick, on the other hand, did some searching and came up with &lt;a href=&quot;http://mattwindsurfs.wordpress.com/2008/06/19/rails-render-in-a-model/&quot;&gt;a blog post from Matt Harvey&lt;/a&gt;. Now, while I&#8217;m sure that works, it seemed like way too much. I came up with a different solution.&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class LogObserver &amp;lt; ActiveRecord::Observer
  def controller
    returning ActionController::Base.new do |controller|
      controller.instance_variable_set('@template', ActionView::Base.new(ActionController::Base.view_paths))
      controller.instance_variable_set('@assigns', {})
    end
  end

  def after_create(log)
    controller.render :juggernaut do |page|
      page.insert_html :after, 'dashboard_logs_top', :partial =&gt; 'logs/log', :locals =&gt; { :log =&gt; log }
    end
  end
end
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;I&#8217;m not especially proud, but it&#8217;s small and it works. And it has specs.&lt;/p&gt;

&lt;p&gt;Also, Juggernaut is pretty sweet.&lt;/p&gt;
          </content>  </entry>
</feed>
