Archive for the ‘Development’ Category

Git versus SVN Presentation

November 24th, 2008

Last week I made a presentation about Git and compared it to Subversion. There is an obvious bias in the slides however, I tried to make a point to show the downsides of Git as well. One slide that is missing is one on security and the idea of Git storing all the commit history on each machine can be a security risk in some scenarios. Feel free to use these slides in your own presentation, but post a link back as a thank you.

Slides: git-presentation

Tags: , , ,
Posted in Development | Comments (0)

RMagick install frustrations

November 24th, 2008

I had a frustrating afternoon after my RMagick mysteriously blew up and refused to run. If you have encountered this error:

“This version of RMagick was created to run with ImageMagick x.x.x (not y.y.y)”

You will be happy to know you just have to uninstall and reinstall RMagick. Apparently the gem is not only specifically built to your machine but also bound to the ImageMagick that was installed at the time.

Posted in Development | Comments (0)

Pivotal Tracker API Ruby Wrapper

November 11th, 2008

I have been playing around with the recently released public API for Pivotal Tracker. In the process of converting this into a Datamapper Adapter, I tested it with some simple Net::HTTP Ruby code. It provides a nice simple, and limited, illustration of what is possible with this public API. One thing I would like to see added to the API however is the ability to limit the number of results when querying with filters. Attached is the slightly modified source code (removed my project id and token key). Tests are included as always, but fair warning, some are brittle! I will post another revision once the Datamapper Adapter is created.


require 'rubygems'
require 'hpricot'
require 'net/http'
require 'uri'
require 'cgi' 

##
# Pivotal Tracker API Ruby Wrapper
# November 11, 2008
# Justin Smestad
# http://www.evalcode.com
##

class Tracker
  def initialize(project_id = changeme, token = changeme)
    @project_id, @token = project_id, token
  end

  def project
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.get(resource_uri.path, {'Token' => @token})
    end

    doc = Hpricot(response.body).at('project')

    @project = {
      :name             => doc.at('name').innerHTML,
      :iteration_length => doc.at('iteration_length').innerHTML,
      :week_start_day   => doc.at('week_start_day').innerHTML,
      :point_scale      => doc.at('point_scale').innerHTML
    }
  end

  def stories
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.get(resource_uri.path, {'Token' => @token})
    end

    doc = Hpricot(response.body)

    @stories = []

    doc.search('stories > story').each do |story|
      @stories << {
        :id => story.at('id').innerHTML.to_i,
        :type => story.at('story_type').innerHTML,
        :name => story.at('name').innerHTML
       }
    end
    return @stories
  end

  # would ideally like to pass a size, aka :all to limit search
  def find(filters = {})
    uri = "http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories"
    unless filters.empty?
      uri << "?filter="
      filters.each do |key, value|
        uri << CGI::escape("#{key}\"#{value}\""
      end
    end

    resource_uri = URI.parse(uri)
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.get(resource_uri.path, {'Token' => @token})
    end

    doc = Hpricot(response.body)

    @stories = []

    doc.search('stories > story').each do |story|
      @stories << {
        :id => story.at('id').innerHTML.to_i,
        :type => story.at('story_type').innerHTML,
        :name => story.at('name').innerHTML
      }
    end
    return @stories
  end

  def find_story(id)
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories/#{id}")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.get(resource_uri.path, {'Token' => @token, 'Content-Type' => 'application/xml'})
    end

    doc = Hpricot(response.body).at('story')

    @story = {
      :id => doc.at('id').innerHTML.to_i,
      :type => doc.at('story_type').innerHTML,
      :name => doc.at('name').innerHTML
    }
  end

  def create_story(story)
    story_xml = build_story_xml(story)
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.post(resource_uri.path, story_xml, {'Token' => @token, 'Content-Type' => 'application/xml'})
    end
  end

  def update_story(story)
    story_xml = build_story_xml(story)
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories/#{story[:id]}")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.put(resource_uri.path, story_xml, {'Token' => @token, 'Content-Type' => 'application/xml'})
    end
  end

  def delete_story(story_id)
    resource_uri = URI.parse("http://www.pivotaltracker.com/services/v1/projects/#{@project_id}/stories/#{story_id}")
    response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
      http.delete(resource_uri.path, {'Token' => @token})
    end
  end

  private

    def build_story_xml(story)
      story_xml = "<story>"
      story.each do |key, value|
        story_xml << "<#{key}>#{value.to_s}</#{key}>"
      end
      story_xml << "</story>"
    end
end

Read the rest of this entry »

Posted in Datamapper, Development, Ruby | Comments (0)

destroy_all with conditions

November 3rd, 2008

In a has_many relationship, there should be a way to add conditions to destroy in order to eliminate an explicit find.


@post.comments.find(:all, :conditions => "name LIKE 'stupid%'").each {|record| record.destroy }

With a patch I recently submitted to Rails core, you can now trim this line into:


@post.comments.destroy_all "name LIKE 'stupid%'"

Jump on over to Lighthouse bugtracker and try out the patch.

Tags: , ,
Posted in Development, Rails | Comments (0)

TextMate reigns supreme with ‘Ack in Project’

September 29th, 2008

The one thing holding TextMate back from Ruby / Rails domination is its horribly slow search functionality. Using ‘Search in Project’ will take what seems like an eternity to pop up any results. The only real attempt at solving this headache was to use ‘Grep in Project’, but it left a lot to be desired including search speed. Now comes the solution, ‘Ack in Project’ was a project created on GitHub back in August to use the much more efficient Ack library for searching. With enhanced output, it has given other IDEs like NetBeans and IntelliJ a swift quick to the balls as to what is the best Ruby / Rails editor.


$ cd /Applications/TextMate.app/Contents/SharedSupport/Bundles/
$ sudo git clone git://github.com/protocool/ack-tmbundle.git Ack.tmbundle

Use Ack in Project with Cmd+Shift+A

Tags: ,
Posted in Development, Rails, Ruby | Comments (18)

Rubyme opens its doors.

August 20th, 2008

I have been working long hours getting this site up and running. The concept was initially drafted after some tutoring work I had done and the difficulty I had in coordinating everything. If you have not yet figured out, the site is called Rubyme (www.rubyme.net). The goal of the site is to provide an easy way for users to find help on anything from specific project difficulties to a more typical tutor style. Currently many of the features are still under heavy development, but the basic functionality is there. I encourage you to sign up and become a tutor. It is a great way to make some money, get exposure, and learn. There will be ongoing patches, so please report any problems to my email address: justin.smestad@gmail.com

Tags: , , , , ,
Posted in Development, JRuby, Merb, Rails, Ruby | Comments (0)

rboard is one step closer to a reality

August 14th, 2008

Radar, a friend of mine in the Ruby community, has finally achieved success with his most recent project. He is working on implementing the ‘ideal forum application’ for the folks over at Rails Forum. I was lucky enough to give him a hand for a small chunk of his code, topic moving! Figured it was blog worthy and if you want to see some intimidating code, rboard is as good as any!

Posted in Development | Comments (0)

JRuby & JTestR in Eclipse

August 11th, 2008

Continuing my rampage upon the JRuby community, I have achieved beautiful success with running my tests inside of the eclipse IDE as a JUnit test. Now I have limited knowledge in the JUnit realm and encourage those to improve upon my approach.

In your eclipse Package Manager sidebar, Right Click -#> Run As.. -#> Run Configurations. Go ahead and select ‘JUnit’ and hit the ‘New Launch Configuration’ button.

Fill in the configuration as follows:

* Run a single test
Project: your-project-name
Test class: org.jtestr.ant.JtestRSuite

Now just open the ‘Arguments’ tab and inside the ‘VM arguments:’ box

-Djtestr.junit.tests=rspec_tests

rspec_tests is the folder where my tests are stored, feel free to change this to something like /test/jtestr/funny_test or whatever structure you store your files in.

I am still trying to figure out a more effecient way to get these test to run under eclipse. Till than I can always fall back on this approach as well as the standard ant task.

Tags: , , , , ,
Posted in Development, JRuby, RSpec | Comments (1)

Git your own server!

August 11th, 2008

With the recent boom of GitHub, there are thousands migrating from old subversion and even cvs servers to git. Surprisingly however, many people would rather pay GitHub to host their site instead of doing it themselves. Well I may be on the git bandwagon, but I am definitely not on the pay-for-git one. I recently setup two git servers (for redundancy). This will be a brief tutorial on getting your own git server running on Debian Etch/Lenny/Sid (or Ubuntu).

First we need to install git. Simple enough with this command:

$ sudo apt-get install git-core git-doc git-svn git-email git-cvs

Now we want to ensure git installed correctly

$ git --version
git version 1.5.6.3

If you are running Debian Etch, you need to use the backports-etch repo to install git >= 1.5. Or compile it from source.

Alright then just follow the commands:

$ sudo apt-get install python
$ sudo apt-get install python-setuptools

Once those are installed just copy paste the following commands. We are going to use gitosis as a way to manage repositories and git access privileges.

$ git clone git://eagain.net/gitosis
$ cd gitosis
$ python setup.py install

If you receive any errors from running the setup.py script, ensure you installed all the packages above from apt-get.

$ sudo adduser \
     --system \
     --shell /bin/sh \
     --gecos 'git version control' \
     --group \
     --disabled-password \
     --home /home/git \
     git

This will setup all your repositories inside of /home/git, feel free to change this to whatever location you desire. Now thats all done, we just need to get your SSH certificate setup so that you can initialize your gitosis install.

This is how it would be done on OSX (this guide for full info on generating SSH keys). From your local machine, issue this command:

$ scp ~/.ssh/id_rsa.pub yourusername@yourserver:/tmp/

Now to wrap this up quickly, go back to your server and setup the SSH key for the gitosis repo.

$ sudo -H -u git gitosis-init < /tmp/id_rsa.pub

If you get an error on initialization then you do not have git >= 1.5. For the rest of us, now we just need to edit the gitosis repo to add/delete users and git repositories! Issuing a simple git push, will propegate the change. For full information, see the gitosis README.

Tags: , , , , , , , ,
Posted in Development | Comments (0)

My Design_fu is lacking, need help!

August 10th, 2008

This time had to come sometime, I have been ignoring it for just too long. I need to find a web designer. For years I have been able to get away with modifying open source layouts and copying trends on other sites. Well it just isn’t going to cut it for the web applications I have coming through the pipe right now. This definitely is an interesting problem that I am sure many software developers face. Exactly how I am going to find someone and build a work relationship remains to be seen. The majority of designers are either of ‘template monster’ quality or they are working for larger media/print corporations which are FAR out of my budget. Maybe I should write 37signals and tell them to add a chapter on this to their ‘Get Real?’ book…

As always, I will keep blogging as the search continues to unfold. Wish me luck!

Tags: , , , ,
Posted in Development | Comments (0)