Configuring CapGun
October 10th, 2009
I’ve long been a fan of Capistrano, the Ruby deployment tool that is typically used for deploying Rails applications. And I’ve also been impressed by the work of Glenn Vanderburg and his colleagues at Relevance. So I took notice when I recently read about CapGun, which is useful for sending email notifications whenever a project is deployed.
The point of this post is that very recently I had the opportunity to install and configure CapGun for a client. The blurb on github told me how to install and configure CapGun. Under the heading of Usage I was encouraged to read the first paragraph:
Good news: it just works.
Well, almost. CapGun does “just work” once you’ve configured it correctly. Included in the config sample to be added to deploy.rb was:
# define the options for the actual emails that go out -- :recipients is the only required option set :cap_gun_email_envelope, { :recipients => %w[joe@example.com, jane@example.com] }
Unfortunately this was not quite complete enough for CapGun to work. Instead it died deep in the bowels of net/smtp.rb:
/usr/local/lib/ruby/1.8/net/smtp.rb:930:in `check_response': 555 5.5.2 Syntax error. 7sm1592402qwb.55 (Net::SMTPFatalError) from /usr/local/lib/ruby/1.8/net/smtp.rb:899:in `getok' from /usr/local/lib/ruby/1.8/net/smtp.rb:828:in `mailfrom' from /usr/local/lib/ruby/1.8/net/smtp.rb:653:in `sendmail' from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:684:in `perform_delivery_smtp' from /usr/local/lib/ruby/1.8/net/smtp.rb:526:in `start' from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:682:in `perform_delivery_smtp' from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:523:in `__send__' from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:523:in `deliver!' from /usr/local/lib/ruby/gems/1.8/gems/actionmailer-2.3.4/lib/action_mailer/base.rb:395:in `method_missing' from ./vendor/plugins/cap_gun/lib/cap_gun.rb:70
The lesson was that the :cap_gun_email_envelope needed to be configured with :from as well as :recipients. And the good news is that the people at Relevance have just accepted my documentation patch.
And the even better news is that now CapGun does “just work”. It’s a very handy tool for keeping everyone in a team informed about deployments in an automated and timely manner.
Rails Camp 5 and Sydney RORO Meetup
June 11th, 2009
I think it’s time I gave a brief update about a couple of professional events within the Australian Ruby community that I’ve recently enjoyed.
Rails Camp 5
Last month over an extended weekend the fifth Australian Rails Camp was held in the Queensland Gold Coast Hinterland. The venue was superb, much fun was had and a great deal of thanks is due to the Brisbane contingent who organised the event.
Having started the weekend working on my own to improve my iPhone development skills, particularly with respect to using ObjectiveResource to integrate an iPhone app with a Rails backend, I was actually very pleased that I didn’t continue on this path beyond Saturday afternoon. From Saturday evening onwards I teamed up with Martin Stannard and Michael Koukoullis to develop a Heroku-like tool called Bivouac. I thoroughly enjoyed our collaboration and learnt much from it. For anyone else considering attending a future Rails Camp I thoroughly recommend getting involved in a team project rather than working alone.
More on Bivouac in a later post. Meanwhile, you can find the source on github.
Sydney June RORO Meeting
Earlier this week the monthly Sydney RORO (Ruby on Rails Oceania) meeting featured a dozen lightning talks. In one of my talks I shared a technique for providing XML in a legacy format via REST, XML Builder and a presenter object. Whilst the example is contrived, the technique is one that I used to handle a requirement for a client recently.
Here are the slides:
In fairness, I must give credit to Obie Fernandez for his coverage of XML Builder in his book, The Rails Way, which gave me a head start.
ActionWebService with Rails 2.2
February 8th, 2009
I encountered a trick for young players the other day when providing XML-RPC web service support within a Rails application.
Since Rails 2.0 was introduced, RESTful web services via ActiveResource have been supported in preference to SOAP or XML-RPC web services. Indeed, ActionWebService was dropped from Rails when version 2.0 was released.
However, there are times when the need to provide an interface to another application mandates the use of SOAP or XML-RPC. Recently I had a need to provide an XML-RPC web service server within a Rails application. Fortunately, a version of ActionWebService has been kept up to date on GitHub together with instructions for implementing it.
As I was developing my support for XML-RPC calls, I found chapter 25 of Thomas and Hansson’s “Agile Web Development with Rails” (second edition) invaluable.
For simplicity’s sake, let’s say my controller was:
class BackendController < ApplicationController wsdl_service_name 'Backend' web_service_api BackendApi web_service_scaffold :invoke if Rails.env == 'development' def foo_bar(args) # method code goes here end end
And here is an XML-RPC test client:
require 'xmlrpc/client' require 'pp' server = XMLRPC::Client.new2("http://example.com/backend/api") result = server.call("FooBar", ["arg1", "arg2", "arg3"]) pp result
Notice that the call is to a method called “FooBar” whereas the method within the Rails controller is called “foo_bar”. If you’re like me you will have originally fallen into the trap of assuming that the remote call will have the same name as the controller method rather than the camel case equivalent.
Rails Camp in the Adelaide Hills
November 23rd, 2008
I think I’ve just about recovered from last weekend’s Rails Camp in the Adelaide Hills. Whether I was hacking or socialising, as the hour got later each evening it just seemed easier to ignore the fact that I was going to pay later for the lack of sleep.
It was worth it though. This was the best attended Rails Camp yet with about 70 Rails developers converging from different parts of Australia. One of the aspects I like about these events is their self-organising nature. The unconference style encourages learning within small groups for much of the event. In my case I was determined to practice using Cucumber, Webrat and Machinist and benefited from the fact that several others were also cutting their teeth on Cucumber.
There are also plenty of opportunities to share with the whole group. At this camp I was fortunate that Pete Yandell, the author of Machinist, was one of those who spoke. I also thoroughly enjoyed the lengthy discussion which was precipitated by Pat Allan’s talk about Freelancing.
Quite apart from the learning opportunities, I appreciated catching up with other Rails developers I hadn’t seen for a while and making new friendships. I’m looking forward to my next Rails Camp already. Hopefully the number of attendees doesn’t increase. I think it has reached its limit for a good unconference.
Dynamic CSS with Rails
October 24th, 2008
I’ve sometimes wondered why CSS isn’t more dynamic.
Take, for example, the styles applied to the sub-menu on the services page of this site. To achieve the highlighting of the current service, I combine a Rails view and CSS as follows:
The Rails View
<div id="<%= @current_service.name %>"> <div id="secondaryNav"> <ul> <% @services.each do |service| %> <li class="<%= service.name %>"><%= link_to service.heading, service_path(service) %></li> <% end %> </ul> </div> </div>
The CSS
#agileweb #secondaryNav .agileweb a, #java #secondaryNav .java a, #coaching #secondaryNav .coaching a, #mentoring #secondaryNav .mentoring a, #overview #secondaryNav .overview a, #advice #secondaryNav .advice a { color: #99CC00; text-decoration: underline; }
Handling a new service
That does the trick nicely until I decide to add a new service. Wouldn’t it be nice to have that CSS regenerated dynamically whenever I create, update or delete a service?
Enter a new Ruby module:
# lib/dynamic_css.rb module DynamicCss def generate_services_nav_links_css return if RAILS_ENV == "test" FileUtils.cd File.expand_path("public/stylesheets", RAILS_ROOT) File.open("servicesnav.css", "w") do |out| service_names = [] services = Service.find :all services.each { |s| service_names << s.name } service_names.each_with_index do |name, i| out.print "##{name} #secondaryNav .#{name} a" if i + 1 < service_names.size out.puts "," else out.puts " {" end end out.puts " color: #99CC00;" out.puts " text-decoration: underline;" out.puts "}" end end end
Then a small adjustment to invoke the css regeneration via a filter in my admin services controller:
class Admin::ServicesController < AdminLayoutController include DynamicCss after_filter :generate_services_nav_links_css, :only => [:create, :update, :destroy] # remainder of controller end
Lastly, to ensure that the servicesnav.css file exists by the time one of the public services pages is requested:
# config/initializers/services_nav_css.rb include DynamicCss generate_services_nav_links_css
Admittedly this is a specific case, but this example shows that it is relatively straightforward to dynamically generate CSS within a Rails app if required.
Code Syntax Highlighting
October 17th, 2008
Having just implemented code syntax highlighting in this blog in addition to Textile formatting, I thought I’d share how I did it.
After a little research, I decided that Arya Asemanfar’s tm_syntax_highlighting plugin looked the most promising. Arya’s blog post about it was particularly helpful.
Prerequisites
Install the oniguruma system library (see link in the plugin README).
Install the ultraviolet gem, which will also install the textpow and oniguruma gems.
sudo gem install ultraviolet
1. Install the Plugin
./script/plugin install git://github.com/arya/tm_syntax_highlighting
2. Copy all themes from ultraviolet:
./script/generate syntax_css
3. Create defaults initializer
# config/initializers/tm_syntax.rb TmSyntaxHighlighting.defaults = {:theme => "mac_classic", :line_numbers => false, :lang => "ruby"}
4. Create an application helper method to parse the Textile and code:
Note: I have used “c0de” instead of “code” here just to enable this code to be parsed!
# app/helpers/application_helper.rb def parse_textile_and_code_syntax(text) text_pieces = text.split(/(<c0de>|<c0de lang="[A-Za-z0-9_-]+">|<c0de lang='[A-Za-z0-9_-]+'>|<\/c0de>)/) in_pre = false language = nil text_pieces.collect do |piece| if piece =~ /^<c0de( lang=(["'])?(.*)\2)?>$/ language = $3 in_pre = true nil elsif piece == "</c0de>" in_pre = false language = nil nil elsif in_pre code(piece.strip, :lang => language, :theme => "mac_classic") else RedCloth.new(piece.strip).to_html end end end
5. Use the helper in the views
<%= parse_textile_and_code_syntax(@blog_post.post) %>
6. Add CSS for horizontal scrolling
pre { margin: 10px 10px; padding: 10px 10px; line-height: 15px; overflow: auto; font-family: "Monaco", "Courier New", courier; font-size: 12px; }
Navigation
Latest Blog Posts
- 11 Aug: RVM, Bundler and Ruby Tracker
- 10 Feb: Ten Years On
- 10 Oct: Configuring CapGun
- 6 Sep: Inspirations for a Ruby DSL
- 28 Jul: At Your Service
Syndication
Tags
actionwebservice automated testing bdd blog bundler capgun capistrano collaboration css cucumber deployment dsl estimating jaoo javascript osdc osdc2008au pdf prawn rails railscamp rake rest rorosyd rspec ruby ruby tracker rvm selenium services syntax highlighting tdd technology unconference wds08 web design webrat xml xml-rpc