How To Edit A Rake Task From A Gem
Apart from having to contribute to the open source project of a gem that you’re using in your Ruby On Rails application in order to edit a rake task in there, you can simply use Rake::Task#enhance to add some codes before and/or after the rake task. Unfortunately, Rake::Task#enhance does not allow adding anything in the middle of the rake task 😢
Eventually, you just need to run the same rake task command rake my:task, and the pre and post actions will be executed as well
How To Use Enhance On rake task
Rake::Task#enhance is execute on the rake task that you intend to “enhance”, so to execute it would look like Rake::Task[‘my:task’].enhance.
It takes in a &block argument that would run after the rake task has completed. I love that you can add binding.pry in this block of code to debug the post rake task action that you intend to enhance too.
The code snippet below enhances the rake task by:
- Generating the translation.js file first
- Removing the previous translation-XXfingerprintXX.js files if any
- Add the current timestamp as the fingerprint for the newly generated js file in step 1.
How To Add Code Before The rake task
Above, we cover how to run the task after the rake task has run. To run something before that, you would need to pass the code as an argument.
Rake::Task['my:task'].enhance(puts("Start my:task")) do puts("End my:task") puts("Start my:new:task") Rake::Task['my:new:task'].invoke puts("End my:new:task") end
If you use capistrano to do deployment, you can refer to their github source code for the after macro.
It uses enhance to synchronous order of the rake tasks to run during deployment.
Since we are providing a &block argument, I would have expected to be able to use the yield keyword to control when to execute the rake task, which is the commonly used in ruby or rails. So for example,
Rake::Task.enhance do puts "Start" yield puts "End" end
I believe this will improve familiarity of the code to fellow rubyists! Good old convention over configuration philosophy!
Note to self: There might be some limitations/problems executing a rake task this way; explore first and maybe propose in rails github 🥶