Minimum viable guard
- Published
- 7 August 2016
- Tagged
Guard is a cool ruby library for automatically performing tasks every time a file changes. But if you're not sure what to expect, it can be hard to set up. Here's the quickest possible setup for Guard.
Use case
In this case, I'm making a quick website prototype in haml. I want to make sure that, whenever I modify one of my haml files, ruby immediately produces the equivalent html file for me in the same directory.
Installation
To set up guard, first you must install it:
gem install guard
Once that's all done, you're ready to go!
Setup
Navigate to the root directory for your project and create a new file, named Guardfile. This is where you tell guard what to do.
Guard runs using a series of plugins, which must be subclasses of Guard::Plugin. There's a few methods you can override for your plugin, but the most important are start and run_on_modifications:
- start runs when the plugin is loaded. It's useful for informing you that the plugin successfully loaded, or for setting up any initial variables you need set up.
- run_on_modifications runs whenever a watched file is modified. We'll talk about watched files in a bit - what you need to know is that
guardwill pass this method an array of paths, corresponding to the modified files.
Let's have a look at a sample plugin for turning haml files into html files:
# I need this to run haml
require "haml"
class Guard::Hamliser < Guard::Plugin
def start
puts "Starting Hamliser"
end
def run_on_modifications(paths)
paths.each do |haml_file|
html_file = haml_file.gsub(".haml", ".html")
# Render the HAML file into the HTML file
File.open(html_file, "w"){ |io| io.puts Haml::Engine.new(File.read(haml_file)).render }
puts "Rendered #{haml_file} to #{html_file}"
end
end
end
You don't need to print a status message for every modification, but I find it handy.
Watching files
The last thing you need to do is tell guard what to watch. You do this with the guard method, which takes one argument (the Plugin subclass to run, in string form) and a block. The block tells guard which files to watch through a series of different commands, but the most basic is the watch method:
guard("hamliser") do
watch %r|.*\.haml$|
end
watch takes a string or regex argument, and matches the path of each changes file against this. You can run watch multiple times within the same block: as one of the watch arguments matches, the path will be passed to run_on_modifications. Here, I specify that I only care about files ending in .haml.
Gluing it together and making it go
Now all that remains is to add the guard syntax to the end of my guard file:
require "haml"
class Guard::Hamliser < Guard::Plugin
def start
puts "Starting Hamliser"
end
def run_on_modifications(paths)
paths.each do |haml_file|
html_file = haml_file.gsub(".haml", ".html")
# Render the HAML file into the HTML file
File.open(html_file, "w"){ |io| io.puts Haml::Engine.new(File.read(haml_file)).render }
puts "Rendered #{haml_file} to #{html_file}"
end
end
end
guard("hamliser"){ watch %r|.*\.haml$| }
To run this from the command line, navigate to your root folder and run the guard command. You're all ready to go!