- loading...
My attempt at sake task management
I’ve used sake intermittently in my workflow. It competes against me writing helper/admin scripts in my ~/ruby/bin folder. Normally, executable Ruby scripts have won. But I think I have a new solution that could make sake a permanent winner for me.
Ruby scripts are easy to create and execute. You just open new file, change the TextMate grammar to ‘Ruby’, type ‘rb’ and press TAB and you’re off and running (the ‘rb’ snippet generates #!/usr/bin/env ruby or a variation of that). You then make the file executable and BAM! you can run the script from any folder in your environment.
Sake tasks are more annoying to write. After creating a new file, you need to create the namespace and task wrappers for your functionality, such as:
namespace 'foo' do
namespace 'bar' do
desc "This task ..."
task :baz do
end
end
end
Your task isn’t instantly executable either. After each change, you need to uninstall the task (sake -u foo:bar:baz) and then reinstall the sake file (sake -i foo/bar/baz.sake) and then run it (sake foo:bar:baz). Perhaps there’s a way to inline edit a sake task, but I can’t see it from the help options.
But once you’ve got your script installed in sake, you get all the wonders that sake provides: a named list (with summary) of tasks (sake -T) and the ability to run those tasks anywhere. Ok, that’s really only one advantage over standard Ruby scripts. But I like it. Oh, namespacing. The baz task exists in a namespace foo:bar. That’s nice too.
So to make me happy, I need a solution to the dubious “create-install-execute” process above. I also want the raw source for all my sake tasks in one place so I can fix/add/change them, reinstall them and move on with my life. I want simple.
So I’ve forked Chris Wanstrath’s empty sake-tasks repo (mine) and added some infrastructure for managing sake tasks. Of course the repo itself is the repository for my sake tasks (which includes a lot from Luke Melia), but most importantly it has a single rake task to reinstall all the tasks without any manual fuss.
The rest of this article assumes you want to have your own repository for your own sake tasks hosted on github. This paragraph is probably unnecessary, but I don’t want to be accused of not being mildly thorough.
Fork the sake-tasks repo
For thoroughness and a chance to demonstrate some gold-medal git-fu, I’ll show two ways: fork my repo and forking the original repo from Chris and pulling my stuff into yours. It’s git, it’s distributed, you can do anything.
If you want to fork my repo and skip a nifty git lesson, go to my sake-tasks repo and click “fork”. Then follow the clone instructions as you normally do when you are blatantly, systematically duplicating someone else’s hard work, using a command that will look something like:
git clone git@github.com:your-github-username/sake-tasks.git
Now, lazy man, you can skip to the next step.
If you want to flex your git-fu, then go and fork Chris’ repo instead. Again, follow the clone instructions.

Now take a moment to reflect on just how empty your repository is. A fine moment in open-source where you’ve essentially cloned an empty repository. Hardly worth the effort, but since Chris is a creator of github then if he creates an empty repository then who am I to disagree. Empty it shall start.
Now let’s pull in the code and tasks from my repo. My repo could be any git repo anywhere on the tubes.
One way you could pull my code into your local repository is to add my repo as a remote and then pull in the goodness:
git remote add drnic git://github.com/drnic/sake-tasks.git git pull drnic master
This is useful if you ever plan on re-pulling from a target repo again in the future.
If you just want to pull from someone’s repo one time only, then you can merge these two lines together:
git pull git://github.com/drnic/sake-tasks.git master
If you get occasional pull requests for your projects, then the latter option is handy to know.
Your local repo is now different to your remote repo (your fork on github) so push it back to your remote:
git push origin master
Installing the sake tasks
I originally created my sake-tasks fork so I could store a git:manpages:install task. I’ve just upgraded to git 1.6 (note to self: I want an ‘upgrade to latest git version via src’ task; UPDATE the repository now includes a git:src:install task to do this) and found some instructions for installing the pre-built manpages. Then I got over excited and refactored all of Luke Melia’s git+mysql+ssh tasks in to my repo so it looked like I’d done a lot of work.
To install all the tasks, first install sake:
sudo gem install sake
Then run the install task (check below for the list of tasks to be installed):
WARNING: This will uninstall any tasks you already have by the same name.
rake install
Now, check that your sake tasks are installed:
sake -T
Gives you:
sake git:analyze:commits:flog_frequent # Flog the most commonly revised files in the git history sake git:close # Delete the current branch and switch back to master sake git:manpages:install # Install man pages for current git version sake git:open # Create a new branch off master sake git:pull # Pull new commits from the repository sake git:push # Push all changes to the repository sake git:status # Show the current status of the checkout sake git:topic # Create a new topic branch sake git:update # Pull new commits from the repository sake mysql:dump # Dump the database to FILE (depends on mysql:params) sake mysql:load # Load the database from FILE (depends on mysql:params) sake ssh:install_public_key # Install your public key on a remote server.
Sexy.
Adding new recipes/tasks
The installer rake task rake install works by assuming that each .sake file contains one sake task. This allows the rake task to uninstall the tasks from sake first, and then re-install it (sake barfs if you attempt to reinstall an existing task). Without the one-task-per-file rule, the solution would be to load all the sake tasks as rake tasks into memory. But I like one-task-per-file; it seems clean.
So, to create a task foo:bar:baz, you’ll need to add a folder foo/bar and create a file baz.sake inside it. Within that file you would then specify your task using namespace and task method calls:
namespace 'foo' do
namespace 'bar' do
desc "This task ..."
task :baz do
end
end
end
To install new tasks or reinstall modified tasks, just run the rake task (rake install or rake).
TextMate users
The latest Ruby.tmbundle on github includes a task command that generates the above namespace/task snippet based on the path + file name. That is, inside the foo/bar/baz.sake file, make sure your grammar is ‘Ruby’ or ‘Ruby on Rails’ and then type “task” and press TAB. The above snippet will be generated ready for you to specify your task.
Summary
So now I have a single place for all my original sake source and a simple rake task to re-install the tasks if I add or modify them. And because its all in one git repo, if other people fork it and add their own tasks then I can steal them.
Related posts:
- Hacking someone’s gem with github and gemcutter Ever used a rubygem, found a bug, and just...
- Migrating project websites to github pages with sake tasks, new websites with jekyll_generator Its almost Christmas time and that means presents. It...
- Future proofing your Ruby code. Ruby 1.9.1 is coming. Bugger. I’m a Ruby monogamist. I use the Ruby...
- TextMate bundles for Merb If you are using TextMate (OS X) or E Text...
- Using Git within a project (forking around) In Star Wars, when Grand Moff Tarkin orders the...
Trackbacks
Use this link to trackback from your own site.






Looks like a cool approach. I’m going to give it a whirl now.
BTW, your command line for adding a tracking branch has a colon where a slash should be. Don’t you wish it was easy as pie to send a diff of a blog post?
@luke – ahh thx for the manual patch report
I’ve wanted to check out sake for a while now, but it always bombed out loading my Rakefiles due to safe level checks. I assumed there was a place I could just edit the sake tasks manually, but I never got around to looking. Will give this a go; thanks.
Hmmm… if sake tasks are going to be at all useful to me, they’re going to have to play well with hoe tasks. Is there some secret trick to getting this working without running into safelevel issues?
I’m tempted to just privately fork sake to remove the safelevel constraints entirely; I’m a big boy and can be responsible. What to do…
@phil – perhaps patch sake to make the safety level configurable via an environment variable?
I’ve added a git:src:install task that determines the latest public release of git, downloads it, and installs it (currently under /usr/local); and then git:manpages:install fetches & installs the applicable man pages.
The tasks probably assume you are on a *nix machine.
The ‘rake install’ task now also has ONLY_FILES and ONLY_TASKS environment variables that are useful for iterative task development. See the README.
As always, nicely done sir.
[...] public links >> installing My attempt at sake task management Saved by crispinbailey on Tue [...]
If your Sake is complaining with “can’t convert true into String”, patch your sake with that fix:
http://err.lighthouseapp.com/projects/466/tickets/246-sake-fails-on-rake-082
.. and your sake will continue to work!
Maxime
[...] First saved by SlyCrayon | 16 days ago Baz First saved by ksskruthic | 18 days ago My attempt at sake task management First saved by Liniscool | 20 days ago Back To Work… First saved by nosophoros | 22 days ago [...]
[...] – bookmarked by 5 members originally found by FlyersVideo on 2008-12-23 My attempt at sake task management http://drnicwilliams.com/2008/08/19/my-attempt-at-sake-task-management/ – bookmarked by 1 members [...]
Checkout visionmedia-commander
it is primarily designed for general purpose executables with multi-word sub-command support but it would do a great job at this, and IMO does a much better job than Sake / Thor.
[...] Nic é um dos que gostou da idéia e fez alguns experimentos. Isso ainda pode evoluir muito, mas uma coisa interessante é criar tarefas de Sake para seu [...]