How many times have you searched how to pass arguments to a rake task? Bake makes it as easy as creating a simple method ( literally ).
For demonstration, we’re gonna create a task that generates a new blog post file for you.
Setup
1) First of all we need to install the gem. Make sure you have at least Ruby 2.5.0. Add Bake to your project’s Gemfile and install it:
$ bundle add bake 2) Create a bake.rb file at the root of your project. This is where the top level tasks will live.
Baking you first task
As I said earlier, just create a ruby method and it will do the job.
# Creates a new post # def new_post(post_name) post_path = "posts/#{post_name.downcase.gsub(/ /, '-')}.md" post_content = "---\ntitle: #{post_name}\n---" File.write(post_path, post_content) end That’s it! Lets run it.
$ bake new_post 'new post' # Creates 2020-07-16-new-post.md To pass strings with whitespaces, wrap them in quotes.
Optional arguments are accepted as well. Maybe we want our posts to be in different extensions sometimes.Let’s add an optional argument to our task.
# Creates a new post # def new_post(post_name, extension = 'md') post_path = "#{post_name.downcase.gsub(/ /, '-')}.#{extension}" post_content = "---\ntitle: #{post_name}\n---" File.write(post_path, post_content) end We can use keyword arguments too! Now we’re going to add categories on our posts.
# Creates a new post # def new_post(post_name, extension = 'md', categories: '') post_path = "#{post_name.downcase.gsub(/ /, '-')}.#{extension}" post_content = "---\ntitle: #{post_name}\ncategories: #{categories}\n---" File.write(post_path, post_content) end And you pass named arguments like this:
$ bake new_post 'bake is awesome' categories='ruby bake' It’s 2020, I need types!
Sometimes it’s useful to coerce the task inputs in other types, since they are always strings. No prob, Bake got you!
Just add some documenting comments above your method and you’re good to go:
# Creates a new post # # @param post_name [String] name of the post to be created. # @param extension [String] file extension of the post to be created. # @param categories [Array(String)] categories of the post. def new_post(post_name, extension = 'md', categories: []) post_path = "#{post_name.downcase.gsub(/ /, '-')}.#{extension}" post_content = "---\ntitle: #{post_name}\ncategories: #{categories.join(' ')}\n---" File.write(post_path, post_content) end Now, instead of wrapping our categories in quotes, we can pass them as comma separated values and they will be coerced into an array of strings.
$ bake new_post 'bake is awesome' categories=ruby,bake Helper methods?
That code is kinda messy. We can extract some methods and not having them showing up as tasks. Make them private that’s it.
# Creates a new post # # @param post_name [String] name of the post to be created. # @param extension [String] file extension of the post to be created. # @param categories [Array(String)] categories of the post. def new_post(post_name, extension = 'md', categories: []) path = post_path(post_name, extension) content = post_content(post_name, categories) File.write(path, content) end private def post_path(post_name, extension) "#{slugify(post_name)}.#{extension}" end def post_content(post_name, categories) <<~CONTENT --- title: #{post_name.capitalize} categories: #{categories.join(' ')} --- CONTENT end def slugify(str) str.downcase.gsub(/ /, '-') end Yeah, that looks much better. And now we can use those methods in other tasks too 😉.
Nested commands
If we want to replace Rake, we need to have nested commands. They’re called recipes in Bake. The tasks are namespaced by their file names. So, let’s do it.
- Create a dir
bake/and a filepost.rbthere. - Copy all the content of
bake.rband move topost.rb(keepbake.rbempty on the root). - Rename the task
new_posttonew.
# in bake/post.rb # Creates a new post # # @param post_name [String] name of the post to be created. # @param extension [String] file extension of the post to be created. # @param categories [Array(String)] categories of the post. def new(post_name, extension = 'md', categories: []) path = post_path(post_name, extension) content = post_content(post_name, categories) File.write(path, content) end private # ... Now you can call it like this:
$ bake post:new 'Nested task!' Listing tasks
To list all available tasks run:
$ bake list Bake has this nice output when listing tasks
You can filter tasks by providing a pattern:
$ bake list post Wrapping up
Bake makes really easy to create tasks. No DSL, no new syntax to learn. Just plain old Ruby methods! If you like it, give it some love by starring the repository on Github.

Top comments (0)