Skip to content

deprec

cherry picking git commits

I've been a little bit slow to learn git. I put that down to it being my fourth version control system (after rcs, cvs and svn). Like a fourth child[1] it brought with it less novelty and I've got less free time to get to know it. That being said, git is a revolutionary advance over subversion and is worth committing the effort to learn.

A little while ago I imported my deployment library 'deprec' to github. This week I discovered a feature that shows me what changes other open source developers have been making on their forks of the deprec codebase.

Github network feature

Clicking on that link shows us a diff for that commit and today Pete Yandell was kind enough to show me how to cherry pick a commit and apply it to my repository.

#First we create a branch and pull thewoolleyman's code into it
git checkout -b thewoolleyman
git remote add thewoolleyman git://github.com/thewoolleyman/deprec.git
git pull thewoolleyman master

# Next we find a commit that interests us
# I chose 09dca130c2826339f3cacff937acee4ef26c6d6c
git log

# Compare this changeset with the previous version
# Note that you can use github for this and the previous step.
diff 09dca130c2826339f3cacff937acee4ef26c6d6c 09dca130c2826339f3cacff937acee4ef26c6d6c^

# Change back to our master branch
git checkout master
git cherry-pick 09dca130c2826339f3cacff937acee4ef26c6d6c

# Push the changes to our remote repo (in this case - github)
git push

I'm pretty excited at how simple it is to see what other people have done with my code and merge it into deprec. Github have provided a feature that I think will really aid in the development of open source. Well done guys!

[1] I don't have kids (yet) but if and when I do I hope they realize this was said in jest!

How to use deprec-1 when deprec-2 gem is released

[2013-12-19 I've not done any work on deprec in the past few years]

deprec-2 preview has been available at www.deprec.org for a while now and is quite stable. When I release it as a new version of the deprec gem it's going to cause users of deprec-1 to see errors. I recommend using deprec-2 for new installations but understand that some people will want to continue using deprec-1 for legacy systems. In preparation for release of deprec-2.0.0 I've some minor modifications so that deprec1 and deprec2 co-exist on the same machine.

To continue using deprec-1.x, install deprec-1.9.3:

$ sudo gem install --version 1.9.3 deprec

Update your projects deploy.rb:

require 'rubygems'
gem 'deprec', '< 1.99'
require 'deprec'

Adding the following to your .caprc will load the correct version of deprec based on the version of Capistrano you're using:

require 'rubygems'
gem 'deprec', '< 1.99' unless respond_to?(:namespace)
gem 'deprec', '>= 2.0.0' if respond_to?(:namespace)
require 'deprec'

You can call capistrano 1 with the command:

cap _1.4.2_ show_tasks

or create an alias by putting the following in your .profile:

alias cap1="`which cap` _1.4.2_"

This will allow you to use the following:

cap1 show_tasks

If everything's working you'll see the deprec tasks listed.

Capistrano and Rake

Last night I read the chapter on automation in Tom Limoncelli's book, Time Management for System Administrators. He spent a lot of time extolling the virtues of Make and how useful it can be in automating sysadmin tasks. Rails makes good use of Rake (think 'ruby-make') to specify administrative tasks. Make/Rake let you specify dependencies in your tasks and by checking file timestamps you can avoid running tasks unnecessarily. This has given me an idea for a change to the way deprec works.

It would be nice if I could restart mongrel on the server using the same command as I use in Capistrano. I'm not suggesting using Rake from my workstation but rather to have many of deprecs cap tasks call a Rake task on the server. So 'cap deprec:mongrel:restart' would call 'rake deprec:mongrel:restart' on the server(s).

There would be two main benefits to this.

Firstly, all deprec tasks would be available from the command line on the target host (obviously some bootstrapping would be required to install Rake, Ruby, etc initially). While I prefer not to have to log in manually to each of the servers in a cluster, there are times when I'm logged in and would like to be able to run tasks locally.

A second benefit is that we could take advantage of dependencies. Compiling PHP, after Apache has already been installed, will no longer cause Apache to be recompiled. Installing Subversion, when Apache has not already been installed, will cause it to be installed. This will reduce the amount of time tasks take to run (which is non-trivial when it involves compiling the likes of openssl!)

Back in May 2007, Bradley Taylor of Railsmachine released a nice gem called Machinify. It's a set of Rake tasks that will install a Rails stack on Ubuntu. It's very nicely written and quite readable. I considered whether I should make deprec dependent on Machinify but as it lacks some of the tasks I want (install, nginx, postgres, etc) I think it would be better for deprec come with its own Rake tasks.

So, it's very tempting to re-architect deprec2 but another thing to consider is this: would we be better off with a working deprec2 next week or a re-designed deprec2 at some later point? I think working code is a better result than ideas that won't get implemented in the available timeframe.

One issue with calling remote rake tasks via Cap is dealing with interactive dialogs. deprec currently deals with this by listening for certain output from the remote call. I can't see why deprec couldn't simply call the remote rake task and listen for the same output. This would allow deprec tasks to be extracted into rake tasks.

So my current thinking is to press on with deprec2 development and then extract the tasks into Rake tasks at some future point.

Deprec Plugins using gem_plugin

I just added automatic plugin loading to deprec2 using Zeds gem_plugin gem. Now, a number of people have been asking if deprec will support other linux distro's (and even other OS's!). While I'm not interested in implementing them myself (until I get sick of Ubuntu) I love freedom so decided to extract all Ubuntu specific functionality into a plugin and allow others to write their own plugins.

You can now write a plugin that will be loaded automatically by deprec2 with no manual intervention or configuration required by the user. Follow the tutorial on the gem_plugin site but here's the core of it:

  setup_gem(name, version) do |spec|
    spec.summary = "The deprec_ubuntu GemPlugin"
    spec.description = spec.summary
    spec.author="Mike Bailey"
    spec.add_dependency('gem_plugin', '>= 0.2.2')
    spec.add_dependency('deprec', '>= 2.0.0')
    spec.files += Dir.glob("resources/**/*")
  end

Make your gem dependent on gem_plugin and deprec. The way this works is clever. When deprec starts, it requires gem_plugin which goes and looks through the other locally installed gems. If it finds any gems that have gem_plugin and deprec as dependencies, it loads their init.rb file.

So installed a third party plugin to support a new distro for deprec be as simple as:

sudo gem install deprec_beos

Note: I'm still hacking on deprec2 - hoping for a preview release this week!