Converting a github issue into a pull request

Converting a github issue into a pull request

Recently someone submitted an issue for one of my open source github repositories (https://github.com/scsmith/language_list). Language list imports a pretty huge list of lanauges as it loads and this was taking a bit of time. There was quite a bit of discussion on the issue, with a fair few branches. Eventaully we were happy with the changes in one of the branches and wanted to bring them into master.

There were two options here, the first is to create a new pull request and just reference the existing issue (you can do this by typing # and using the autocomplete). However I also managed to find this stackoverflow question and answer giving a more preferable option. You can convert an existing issue into a pull request itself. You need to use the github api though but this is pretty easy using curl:

curl --user "your_username:your_password" --request POST --data '{"issue": "4", "head": "username:reponame", "base": "master"}' https://api.github.com/repos/username/reponame/pulls

In this head is the repo you want to bring in and base is the subject of the pull that you want to merge to.

There’s also a site that can do this for you http://issue2pr.herokuapp.com/ but you will have to give full access to your private repos. Personally I find the curl approach pretty simple and really liked this option. Remember to head over to the stackoverflow question and upvote the answer if you use it!

Display error_messages_for for a single flash error using a helper

So error_messages_for has been deprecated in Rails 3. However, you can still download the plugin from here and it’s still in use in a number of projects that we come across. It’s quite often that you see flash error messages appear outside of this error messages for style box but what if you just wanted to display a standardised form across your page.
In it’s simplest form the standard error_messages_for accepts an active model object and will display all of the errors found on that object. But what if we want to just pass in the error message that it should display?

The following snippet allows you to make use of the same template used by default but accepts a string containing the error message.

  def error_from_message(error_message, options = {})
    return nil unless error_message
    
    header_message = options[:header_message] || t(:header, :count => 1, :scope => [:activerecord, :errors, :template], :model => 'item')
    message = options[:message] ||  t(:body, :scope => [:activerecord, :errors, :template])
    
    contents = ''
    contents << content_tag(options[:header_tag] || :h2, header_message)
    contents << content_tag(:p, message)
    contents << content_tag(:ul, content_tag(:li, error_message))
    content_tag(:div, contents.html_safe, :id => 'errorExplanation', :class => 'errorExplanation')
  end

If you place that into your application helper you can then call the following in the view to render the standard active model style error message for the string you supply:

<%= error_from_message flash[:error_message] %>

You can also pass some of the standard parameters to change the tag or override the default header message. There’s nothing amazing in this but hopefully it will at least show where to get started to access the standard i18n translations used by the Rails helpers.

Some really quick git helpers

Here I’ve added a couple of useful tips for working with git. I’ll keep adding to it as I think of more but for now it’s a start.

So we all know it can be dangerous to remove remote branches and tags but once we know we need to do it what can we do?

Delete a Branch Locally:

$ git branch -d branch_name

Delete a remote branch:

$ git push origin :branch_name
This basically pushes nothing to the branch resulting in it being deleted.

Change the path (url) of a remote branch:

git remote set-url remote_name new_path

Delete a Tag Locally:

$ git tag -d tag_name

Delete a remote tag:

$ git push origin :refs/tags/tag_name

git ls-files

This one can be especially useful if you accidentally reset head –soft and want to delete your untracked files. In order to list all untracked files use $ git-ls -o. You could then for example run $ git ls-files -o | xargs rm to delete all of these files. Be aware that this command will list all files though. Including those you chose to ignore.

Update: It’s been a while since I’ve updated this but I thought I’d add a few more that I’ve found really useful lately:

Show all branches containing a commit:

$ git branch --contains 3a98e3
Make sure you git fetch before running this locally. If the commit isn’t found then git will probably list all the arguments as if `–contains sha` isn’t a valid option. If the commit is known but not on a branch you’ll see nothing.

You can also check remote branches with:
$ git branch -r --contains 3a98e3

Remove merged branches

Be careful this this one! Make sure you’re on master before you run this too!
git branch --merged | grep -v "\*" | xargs git branch -d

This will do the following:

List all branches that have been merged with the current branch, remove the entry with * as a prefix (the current branch), delete each branch name extracted by the previous grep.

 

Using factory girl in a Rake task – uninitialized class variable @@configuration in Rails

Over the last few days we have been working on a Rails 2.3 app for a client. We wanted to create a rake task that adds a couple of entries to the database (Seeds.rb is obviously better if you are seeding) and thought that we would use factory_girl to help us do this.

When we added factory girl we created something like the following:

require 'factory_girl'
require File.dirname(__FILE__) + '/../../spec/factories.rb'

namespace :db do
  desc "do something"
  task :create => :environment do
     ...
  end
end

When running this rake task we got the following error which seemed really confusing:

uninitialized class variable @@configuration in Rails
/Users/stevesmith/Documents/projects/profinda/.bundle/ruby/1.8/gems/rails-2.3.10/lib/initializer.rb:20:in `configuration'
/Users/stevesmith/Documents/projects/profinda/.bundle/ruby/1.8/gems/factory_girl-1.2.4/lib/factory_girl.rb:25

We were loading the environment so what was the problem? Well actually it’s pretty obvious once you know. In the above example we are trying to load factory girl before we actually set up the rails environment which won’t work.

Instead if you do the following everything runs fine:

namespace :db do
  desc "do something"
  task :create => :environment do
     require 'factory_girl'
     require File.dirname(__FILE__) + '/../../spec/factories.rb'
     ...
  end
end

This is really obvious if you think about it but it might just save someone a few minutes of debugging!

Multipart Body – A gem for working with multipart data

Multipart queries are used quite a lot in the transfer of data around the Internet. There are a number of projects out there that will generate multipart content such as email libraries and even web frameworks for uploading and working with files. When we came create parts of CloudMailin we couldn’t find a gem that would easily allow us to encode multipart content the way we wanted to. We could have used a library that already this ability it baked in but most of them didn’t work with eventmachine and if they did then we couldn’t be sure that they would work with any testing tools that we created later that didn’t rely on eventmachine. Although loads of libraries were implementing this code we couldn’t find anything that was standalone that we could just use across any of the different libraries that could post content.

In order to solve this issue we created our own internal multipart creation code. This weekend we have released that code as a gem called multipart_body. This gem is far from perfect and we have a list of things that we don’t have time to add and we would love some help with but the code has been useful to us so we hope it will be useful to others too.

The gem itself consits of two parts. Multipart body and the parts. To get started just install the gem


$ gem install multipart_body

Once the gem is installed you can create a form-data multipart body using this quick hash shorthand.

require 'multipart_body'
multipart = Multipart.new(:field1 => 'content', :field2 => 'something else')

To get a little more control you can create the parts yourself and use them to create the body:

# using a hash
part = Part.new(:name => 'name', :body => 'body', :filename => 'f.txt', :content_type => 'text/plain')

# or just with the name, body and an optional filename
part = Part.new('name', 'content', 'file.txt')
multipart = Multipart.new([part])

You can also pass a file to the multipart hash to automatically assign the filename:

require 'multipart_body'
multipart = Multipart.new(:field1 => 'content', :field2 => File.new('test.txt'))

The resulting output can then be created as follows:

part.to_s #=> The part with headers and content
multipart.to_s #=> The full list of parts joined by boundaries

So the following code example will create the output that follows:

multipart = MultipartBody.new(:test => 'content', :myfile => File.new('test.txt'))
------multipart-boundary-808358
Content-Disposition: form-data; name="myfile"; filename="test.txt"

hello
------multipart-boundary-808358
Content-Disposition: form-data; name="test"

content
------multipart-boundary-808358--

Like I said before the gem is far from perfect. At the moment it doesn’t have any documentation and it is missing quite a few features. By default it assumes you are creating form-data content and encodings are completely missing at the moment.

Hopefully though with a little bit of help it can provide a great starting block for anyone wishing to implement multipart bodies so that each library doesn’t have to re-invent this. If anyone has any time I’d love to see patches to bring this up to something much more useful.

Automatically prepending url’s with http://

Recently we added functionality that allowed users to include links to images that they uploaded to one of our sites. In order to make the experience as easy as possible for users we allowed them to enter the url with or without the protocol (http:// or https://).

In order to make sure that any of our models that stored the information would always return a link with the protocol in it I wanted to create a simple mixin that would override the existing link method returned from the database and prepend http:// to it if it needed to.

Checking for the protocol and inserting it
This is actually quite a simple method. The following code was used to override the source_url method that was returning the link from the database.

def source_url
  link = super
  "#{link.match(/(http|https):\/\//i) ? '' : 'http://'}#{link}"
end

Since I was going to add this to a number of models it made sense to convert this to a mixin that could be used on any of the modules.

module Protocolize
  def self.included(klass)
    klass.class_eval do
      def self.protocolize(link_method)
        define_method link_method.to_sym do
          link = super()
          return nil if link.blank?
          "#{link.match(/(http|https):\/\//i) ? '' : 'http://'}#{link}"
        end
      end
    end
  end
end

This can then be called using the following in your model:

include Protocolize
protocolize :method_name

Notice that you have to explicitly call super() with params and not just super when you use it within define_method. If you don’t you will get the following error:

implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.

Just a tiny snippet that might be useful to people to ensure their links work correctly.