iDunno
Categories
Looking glass
Navigate/Search

Released croc 1.0

I finally got around to releasing croc. Nothing crazy in this release, just some cosmetic changes and a real gem on RubyForge.

Croc indexes your local gem rdocs and generates a web page you can use to search and access them, similar to gotapi.com. It’s handy because it covers all your gems and is available when you don’t have an Internet connection, like when on a submarine.

Install it like this:

  $ sudo gem install croc

And run it like this:

  $ croc

This will index your rdocs, optionally installing rdocs for Ruby and Stdlib. In the end, croc creates ~/.croc/index.html. Open that HTML file and start searching!

Here’s a screenshot:

Searching with croc

Search and access your local rdocs with croc

Croc indexes your local gem rdocs and generates a web page you can use to search and access them, similar to gotapi.com.  It’s handy because it covers all your gems and is available when you don’t have an Internet connection.

Install it like this:

  sudo gem sources -a http://gems.github.com
  sudo gem install dmeiz-croc

I’ve only tested on Mac. I’ll submit this to RubyForge after a few tweaks. All feedback is appreciated. Send email to dan at methodhead.com.

Using Thor for Rails tasks

Thor is a cool alternative to Sake. With Thor you can quickly write scripts for the command line with sensible argument handling. Here I show how it works well with Rails.

I’ll often need to nudge my development database into some peculiar state for development or troubleshooting. In most cases it’s easiest to work with ActiveRecord models to make these changes, so I start script/console:

  >> User.find_by_email("dan@methodhead.com").update_attribute(:password, "pistolwhipped")

After doing that way too many times, I put it in a script:

  #!/usr/bin/env /Users/dan/my_rails_project/script/runner
  User.find_by_email("dan@methodhead.com").update_attribute(:password, "pistolwhipped")

These little scripts worked great, but started cluttering my clutter. So I put them all into a Thorfile:

  require 'config/boot'
  require RAILS_ROOT + '/config/environment'

  class My < Thor
    desc "reset_password", "Reset your password"
    def reset_password()
      User.find_by_email("dan@methodhead.com").update_attribute(:password, "pistolwhipped")
    end
  end

The only special bit to this Thorfile is requiring the Rails environment there at the top.

I put this Thorfile just above my RAILS_ROOT directory to keep from bothering other developers with my petty tasks. Now all my tasks are in one place:

  $ thor -T
  Tasks
  -----
  my:reset_password    Reset your password

  $ thor mine:reset_password

Wait, now I can’t log in.

Merging in Git is Kinda Rough

I like git, but sometimes I get lost when a merge conflict happens. I usually flail my way through. Here are some of my moves.

I give you a conflict. I’ll commit a file into master, create a topic branch and change it, and then change it again back in master.

  $ git init
  $ vi foo.rb # puts "Hello world."
  $ git add .
  $ git commit

  $ git co -b topic
  $ vi foo.rb # puts "Goodbye world."
  $ git commit -a

  $ git co master
  $ vi foo.rb # puts "Wake up world."
  $ git commit -a

When I merge topic into master, I get the conflict:

  $ git merge topic
  Auto-merged foo.rb
  CONFLICT (content): Merge conflict in foo.rb
  Automatic merge failed; fix conflicts and then commit the result.

The working file doesn’t look too bad.

  <<<<<<< HEAD:foo.rb
  puts "Wake up world."
  =======
  puts "Goodbye world."
  >>>>>>> topic:foo.rb

Unfortunately, my code is usually freakish spaghetti, so the working file looks more like an ASCII port of Centipede. I liked how Subversion dumped copies of the conflicting files so I could see each side of the conflict. Git doesn’t give you these, but you can get them. Here’s the hard way, but it illustrates somes some lower-level interrogation commands and the nutty fundamentals of Git:

  $ git ls-tree master foo.rb
  100644 blob ff128a16618164a0edaa7d3259bb02cbd7917a32    foo.rb
  $ git cat-file blob ff128a16618164a0edaa7d3259bb02cbd7917a32
  puts "Wake up world."

  git ls-tree topic foo.rb
  100644 blob 6e96df5f6d698f9e1d62d588c1ce84a299bbdba9    foo.rb
  $ git cat-file blob 6e96df5f6d698f9e1d62d588c1ce84a299bbdba9
  puts "Goodbye world."

Here’s an easier way to get at the object names involved in the conflict:

  $ git ls-files -u
  100644 e76947b1956d226e09c800639e526b7a986fa64c 1       foo.rb
  100644 ff128a16618164a0edaa7d3259bb02cbd7917a32 2       foo.rb
  100644 6e96df5f6d698f9e1d62d588c1ce84a299bbdba9 3       foo.rb

Clearly, 1 is the common ancestor, 2 is master and 3 is topic. Ok, maybe not so clear. Anyway, let’s take the topic:

  git cat-file blob 6e96df5f6d698f9e1d62d588c1ce84a299bbdba9 > foo.rb

git-diff doesn’t show what I’d expect:

  $ git diff
  diff --cc foo.rb
  index ff128a1,6e96df5..0000000
  --- a/foo.rb
  +++ b/foo.rb

But if I add it, it makes more sense:

  $ git add .
  $ git diff --cached
  diff --git a/foo.rb b/foo.rb
  index ff128a1..6e96df5 100644
  --- a/foo.rb
  +++ b/foo.rb
  @@ -1 +1 @@
  -puts "Wake up world."
  +puts "Goodbye world."

I’ll just commit it and move on with life:

  $ git commit

Ok, I guess merging in Git is not that bad. I’m sure you’ve got a slick way of merging with Git. Please share!

Update

I submitted some small patches to the git-merge documentation. I think it is helpful, but now that I’ve learned more about Git, I think there is so much more that could be said!

RubyNation

I hit RubyNation this week. As Ruby conferences go, RubyNation is a toddler, but since it was my first, it was the best I’ve ever seen.

The theme was “essence over ceremony,” ceremony being the hoops our technology makes us jump through, essence the place we’re jumping to. More fun was Smarticus’ theme, “Test all the fucking time,” which got good mileage through the whole show.

Neal Ford kicked things off with his essence over ceremony talk. Angelina Jolie was his metaphor for seducing the enterprise with Ruby, so we got a few leggy slides. The girl in the crowd complained about the Brad Pitt deficit. Damned if we didn’t get a Brad Pitt slide in each remaining talk.

I went to the conference to see Yehuda Katz. His talk was kind of a non-event for me, but he added to the conference nonetheless. He knows a lot and has a confident, direct personality which made him fun in the audience with constructively wry remarks. I got a real kick out of chatting with him at the happy hour.

Giles Bowkett was great. His talk was more of a Keynote performance. It was a little about Archaeopteryx and then a this-world-is-ours-if-we-want-it rant. I’m not really sure if that was even the point he was trying to make, but who cares, it was fun.

The other speakers were good and I left feeling motivated and inspired to contribute more to Ruby and the community. Fortunately, this afterglow will wear off about halfway through my first cup of coffee back in the office. Cubicles suck the essence out of anything.

Still, an ember is there. I’ll cup my hands around it, keep it close and do something good.

Installing Merb and DataMapper Edge

I’m trying to learn Merb and DataMapper. Installing the stable gems is the smart thing to do, but I want to play with edge. Both projects are young and moving fast, so keeping my local gems up to date is a hassle. I wrote a script to update my gems.

I first had to install some dependencies with:

  sudo gem install addressable english

Plus I had to clone the git repositories for these projects (you know, with something like git clone git://github.com/wycats/merb-core.git; search for them on github):

  • dm-core
  • dm-more
  • do
  • extlib
  • merb-core
  • merb-more
  • merb-plugins

Gulp, that works out to a lot of gems. For better or worse, this script updates and installs them all:

  SRC=/Users/dan/Projects/numz/src

  cd $SRC/merb-core
  git pull
  rake gem install

  cd $SRC/merb-more
  git pull
  rake gem install

  cd $SRC/merb-plugins
  git pull
  cd $SRC/merb-plugins/merb_helpers
  rake gem install
  cd $SRC/merb-plugins/merb_rspec
  rake gem install

  cd $SRC/extlib
  git pull
  rake gem install

  cd $SRC/do
  git pull
  cd $SRC/do/do_mysql
  rake install
  cd $SRC/do/data_objects
  rake gem install

  cd $SRC/dm-core
  git pull
  rake gem install

  cd $SRC/dm-more
  git pull
  rake gem install

Mocking with Mocha

If you’re into testing, you’ll find you can cover more of the difficult corners
of your code by mocking. Libraries like Mocha make the job easier. I’d give
you some simple examples, but this Quick Start is just too good; I use it all the time.

Here is a more advanced use I discovered. I wanted to verify the XML I was
posting to a web service was correct. The method to test looked something like
this:

  class DataPoster
    def self.post_data(url, data)
      xml = data.to_xml
      post(xml) # this method calls Net::HTTP.post() with logging and error handling
    end
  end

Most of my Mocha code is one-liners like in the Quick Start, which would look like:

  DataPoster.expects(:post).with("http://localhost:3000", "foo")

But instead of passing in fragile strings like “foo” for every
scenario, I’d rather use REXML to verify the XML, so I pass a block to with():

  DataPoster.expects(:post).with do |url, xml|
    assert_equal "http://localhost:3000", url

    doc = REXML::Document.new(xml)
    assert "foo", doc.elements["data"].text

    true
  end

The block returns true if the expectation is met. This is an easier
way to verify big, hairy blocks of XML.

First Post

Some chords while the kids destroyed their playroom idontknow.mp3.