Gradual automation in Ruby

… and check why 5600+ Rails engineers read also this

Gradual automation in Ruby

It’s the simplest piece of Ruby code you’ll read today. I originally stumbled upon it here, where it’s referred as do-nothing scripting. I have yet another name for it, though: Puts-First Automation or Puts-Driven Automation.

Problem

You want to codify a manual process like setting up another instance of your e-commerce app. It may involve several steps with varying potential for automation (like seed the db, set up a subdomain, set up admin account).

  • Solution 1 📖: lay out all steps in a wiki page and teach people to conform.
  • Solution 2 🧠: don’t even document the steps, keep it in your own head. Have people always come to you or discover it from scratch, develop tribal knowledge.
  • Solution 3 🖲: make everything happen at the push of a button in your glossy dashboard app. Spend weeks implementing it and months maintaining it. Lie to yourself that this is good ROI.
  • Solution 4 ⚙️: skip the UI part, write a script that automates it all. Wonder why people don’t use it.
  • Solution 5 📝 + ⚙️: make a do-nothing script that only tells you what to do next. Gradually automate it where it makes sense.

An example

The original example is in Python. This is how I once did it in Ruby. You can see why it’s called Puts-First Automation — at first you puts what has to be done, and you’re happy to have your steps documented. Then you gradually automate, only when you think it’s worth it. You can see here how one step is done manualy, and the other is automated.

STEPS = [
  -> {
    puts "Please open https://my.hosting/dashboard"
    puts "and create a new subdomain."
  },
  -> {
    puts "Creating admin user"
    system(%q{ heroku run -a my-app rails r "User.create(name: 'admin')" })
    puts "Created admin user"
  },
]

def ask_to_continue
  puts 'Continue? [Y/n]'
  input = STDIN.gets.chomp
  unless input == '' || /^[Yy]$/.match(input)
    puts 'User cancelled.'
    exit
  end
end

STEPS.each_with_index do |step, i|
  puts "---------------------------------"
  puts "Step #{i}"
  puts "---------------------------------"
  puts
  step.call
  puts
  ask_to_continue if i < (STEPS.size - 1)
end

Advantages of Puts-First Automation

  • It’s version controlled just as the rest of your stuff.
  • It’s easy to start with — at the beginning nothing needs to be automated.
  • It can keep track of your progress (as opposed to a wiki page)
  • You can automate just some steps, leave the rest to be done manually

I bet you can make the above snippet better!

Send me a gist showing how you do it and I’ll link your example here. DMs open.

Got comments? Reply under this tweet.

You might also like