Automation with RStakeout 15 comments

posted Friday, August 31, 2007 by topfunky

autotest is a fantastic tool. If you’re not using it, you’re missing out on a large part of the joy that life has to offer.

Ryan Davis and Eric Hodel can stop reading this article now.

For everyone else,

Customizable File Watching With rstakeout!

Mike Clark wrote a ruby implementation of a tool to watch files, then run any arbitrary command.

I modified it to look for Test::Unit or rSpec output and pop up a growl notification also. (Apparently the original author of the Mac OS X native app also did the same.)

In any case, this is a really useful tool. Autotest won’t run in Test::Unit mode if you have a spec directory, but rstakeout can be told to run any command when files change. It’s not as smart as autotest (it won’t match the command to the name of the file that changed).

Download

Get rstakeout from one of my Subversion repositories.

http://svn.topfunky.com/public/scripts/rstakeout.rb

Usage

rstakeout "command to run" 'files to watch' 'more files to watch'

It’s most useful when you can use Ruby’s file globbing instead of the shell’s. If you do something like '**/*.rb', Ruby will recurse into all subdirectories. The shell will only go down a single directory, so quote the final arguments so they will be passed to Ruby.

Examples

Rerun a single unit test when the implementation or test file is saved:

rstakeout "ruby test/unit/user_test.rb" 'app/models/user.rb' 'test/unit/user_test.rb'

Run the unit tests when model files are saved:

rstakeout "rake test:units" 'app/models/*.rb' 'test/unit/*.rb'

Run a single functional test, then run flog and filter the output with grep. This will show if your code is becoming more complicated or less.

rstakeout "ruby test/functional/orders_controller_test.rb && 
            rstakeout "ruby test/functional/orders_controller_test.rb && \
                       flog -a app/controllers/orders_controller.rb | \
                       grep 'OrdersController#checkout'" 'app/**/*' 'test/**/*'
            
            Loaded suite test/functional/orders_controller_test
            Started
            ..............................
            Finished in 3.536267 seconds.
            
            30 tests, 74 assertions, 0 failures, 0 errors
            OrdersController#checkout: (56.5)
            OrdersController#checkout_with_google: (17.6)
            OrdersController#checkout_with_paypal: (15.9)
            #x000A;           flog -a app/controllers/orders_controller.rb | 
            rstakeout "ruby test/functional/orders_controller_test.rb && \
                       flog -a app/controllers/orders_controller.rb | \
                       grep 'OrdersController#checkout'" 'app/**/*' 'test/**/*'
            
            Loaded suite test/functional/orders_controller_test
            Started
            ..............................
            Finished in 3.536267 seconds.
            
            30 tests, 74 assertions, 0 failures, 0 errors
            OrdersController#checkout: (56.5)
            OrdersController#checkout_with_google: (17.6)
            OrdersController#checkout_with_paypal: (15.9)
            #x000A;           grep 'OrdersController#checkout'" 'app/**/*' 'test/**/*'

Loaded suite test/functional/orders_controller_test
Started
..............................
Finished in 3.536267 seconds.

30 tests, 74 assertions, 0 failures, 0 errors
OrdersController#checkout: (56.5)
OrdersController#checkout_with_google: (17.6)
OrdersController#checkout_with_paypal: (15.9)

Lather, rise, repeat with Heckle or any other testing tool.

I’m using this to generate PDF documents using my automated system for PeepCode Press.

rstakeout "ruby script/generate code_review" '**/*.textile'

I use a shell shortcut to reuse the previous command.

$ some --long shell command
$ rstakeout "!!" 'files/**/*'

Or with autotest…

Ryan Davis pointed out that you can do something similar with flog and autotest by hard-coding this into your ~/.autotest file:

Autotest.add_hook :green do |at|
  system "flog app/controllers/users_controller.rb | grep \#update" 
end

Incomprehensible Statistics

For completeness:

rstakeout  = 73.7304101610032
autotest   = 909.440236256987
ratio = autotest / rstakeout
      = 12.3346694297654   # <-- zomg! look here!!!

# I have no idea what these numbers are here for,
# or what they mean.
ratio - Math::PI
= 9.19307677617561

target = autotest / Math::PI
= 289.483818093921

target - rstakeout
= 215.753407932918

A Year of PeepCode!

Somehow, it’s been a year of PeepCode!

Yes, I’ll stop these self-congratulatory posts soon. In the meantime, buy a 10-pack and get 2 free screencasts, or a 5-pack and get one free. Offer good through Friday, September 7.

And the first PeepCode Press PDF is now available for purchase in draft form. Rails Code Review is seventeen chapters of common mistakes in Rails apps, and examples of how to write better code instead.

Finally, I have about 15 PeepCode t-shirts that were printed with an experimental process. Early users have reported that the printing washes off after the first laundering. But hey, at least you’ll have a nice black t-shirt! I’ll send you one at my expense, anywhere in the world.

  • Send an email to peepcode@topfunky.com with FREE SHIRT in the subject.
  • Include your shirt size, and male or female
  • Include your mailing address (which will only be used to send you the shirt)
15 comments

Leave a response

  • Gravatar icon meekish

    This could be useful for so many things (Flex development using TextMate comes to mind). How about an rstakeout.com site for community rstakeout script sharing?

  • Gravatar icon Michael

    Hi Geoffrey! Any idea when we can expect the third rspec-episode on peepcode? My Subscription Pack is way too fat at the moment! ;-)

  • Gravatar icon topfunky

    @Michael: It’s next on my list. I’ve been working on the PDF for a while and wanted to get it out there, but I’ll be working on rSpec III this week.

    Also, I seem to have found some weird Haml bug (see repeated shell output in the flog example above). I’ll try to figure out what’s happening.

  • # I have no idea what these numbers are here for, or what they mean.
    ratio – Math::PI

    I’m pretty sure that was just Ryan pointing out that Vlad was 1/PI the complexity of Cap.

  • Gravatar icon topfunky

    Ah, thanks for the clarificaton.

    Also, there’s one shirt left!

  • Gravatar icon topfunky

    The shirts are spoken for. Thanks for playing!

  • Gravatar icon Skyblaze

    We want your t-shirts also here in italy :)

  • Gravatar icon chris

    The shell will only go down a single directory,

    Note that this is wrong for the zsh. I really can recommend the zsh, it makes your (shell) life so much easier.

  • Gravatar icon topfunky

    @chris: Nice. I’ll have to check out the zsh. I know that Zed Shaw likes the fish shell…I wonder if it does that.

    And, another example from today…regenerate Merb documentation when code files are edited:

    rstakeout "rake rerdoc" 'lib/**/*'

  • Great writeup – I’m loving the flexibility of rstakeout.

  • Grr… I just wrote a shell script that does exactly the same as this see:

    http://francis.blog-city.com/just_running_rspec_on_one_thing_while_you_fix_it.htm

    Never mind – works without ruby. Doesn’t do the Ruby file globbing tho’.

  • Just pastied up a link with some code to use Snarl for those of us on Windows, plus a simple script for those who just want to type something like

    watch_model article

    http://pastie.caboo.se/110142

    Enjoy

  • Gravatar icon nathan

    er how do i use this? i have rstakeout.rb file but where do i put it? have copied into the rails directory i am working from but no luck i just get

    -bash: rstakeout: command not found

    cheers nathan

  • Gravatar icon topfunky

    You could put it in script and call it from there

    ./script/rstakeout "rake test"

    For global use, I put it in bin and add it to the shell’s PATH.

    In either case, make it executable:

    chmod +x ./script/rstakeout

  • Hi, I blatantly copied Francis’ idea and added Snarl support (instead of replacing Growl) so that with win32, Snarl should be used automatically. See my version of the pastie.

    I also think that rstakeout should (at least optionally) re-evaluate the glob every loop iteration so that new files would be included as well.

Your Comment

Nuby on Rails

Geoffrey Grosenbach / Ruby / Code / Graphics / Design / Rails / Merb / Javascript / CSS

Ads by The Lounge

Manufactured with

Subscribe

Subscribe (RSS)