Subversion

Posted by Chuck Vose Fri, 21 Apr 2006 15:32:28 GMT

I’m finally learning, oh yes.

The reason IDE’s make it so difficult to copy folders around is because it’s an incredibly difficult process. In order to copy in Subversion you have to copy the folders/files, delete any .svn directories in each level of a folder, then those folders/files have to be added to the repo.

Very complicated process which has been killing me lately. I should have known better; how not DRY of me to copy a folder…

Posted in  | no trackbacks

Why Do Unit Tests Exist?

Posted by Chuck Vose Thu, 20 Apr 2006 19:39:00 GMT

Holy crap I finally figured out why unit tests exist! To give me something to think about in the shower. Yep, simple as that.

No, wait, there are two really good uses off the top of my head: packaging and testing filesystem crap.

The first use is if you’re exporting a plugin for later use (or for general distribution). In this scenario there’s a fairly good chance that the user importing your plugin has messed up their install or is using a database that isn’t the same version or even the same type as the one you’re using.

In either case if you have unit tests and none of them fail then you know that the database probably isn’t at fault.

The second use is for filesystem crap. I can still count the number of times I’ve messed up the permissions on a folder only to find it after a half hour of debugging. This should never happen and there are wonderful tools to prevent it. `ri File` and `ri FileUtils` should get you started if you’re curious.

Specifically I’ve been working on a photo upload admin because I don’t understand file_column. In this I occasionally have to make a directory (okay, every time I upload something that isn’t a graphic) and it would be really nice to know that when I post it onto our production server that it’ll work when I release it into the wild.

Under this column is a wonderful addition to test_helper to check that things are correctly set in other places. Since rake is seperate from the dispatchers it could check their permissions, check the permissions of the public and log folders, and a myriad of other wonderful tests that could help newbies get on their way.

Rake is already pretty good at this but it serves as an excellent example of one use for unit testing.

Posted in ,  | no trackbacks

Hiring developers

Posted by Chuck Vose Thu, 20 Apr 2006 19:33:00 GMT

Background

After a lot of thought and an enlightening article by Joel Spolsky , I’ve come to the following conclusion: Hiring new developers is almost never the answer to the problem of having too many programming projects.

We have that problem right now. Demand is very high and Tynan no longer has much time to code due to business requirements. So we have at least four pending projects, two of them very large, and three on-going projects but only 1.5 developers.

No, we really have much closer to 3/4 of a developer. If that.

I spend roughly 1/3 to 1/2 of each day doing server related projects. Unbreaking the repo is a pretty consistent project (probably because Tynan and I are bad citizens but we don’t know any better), as well as maintaining the email, doing backups, messing with mysql, doing security checks and making sure apache is still running.

I usually consider it a good day if I get in two hours of programming before I’‘m too tired to continue. It happens fairly often that after all the server management I’m just too tired to get in the zone so I pour out crap that I have to re-program later on.

Tynan is in an even more painful place. I’ve only seen him work once but he spent the whole day on the phone with customers. He’s figured out what to do with his problem to some degree but I estimate him at somewhere around 1/4 to 1/3 of a developer.

Solutions

What the hell do you do? Adding more developers is the natural idea; it seems like it would work brilliantly. But anyone that’s worked with another developer knows that this is dead wrong. As Brooks points out in The Mythical Man-Month adding a developer increases the complexity of communication exponentially.

Gamble with time

So that’s out, the only thing left is to reclaim lost developer time and gamble a little bit. By hiring a secretary, a server admin and a tester will the two developers produce enough to offset the three extra salaries?

It’s a business choice, the sort of thing I really suck at. If the developer is twice as productive will it be worth twice the money or will something happen where the developer isn’t twice as productive? How long will it take to train and hire a server admin? How much of this time will be from the developer? Can we afford to lose the main developer for the time it takes to train the server admin?

What about a secretary? How long will it take to train the secretary to find all the information in the office? How long will it take to organize the information so they can find it period?

Time management

Maybe that’s not the only solution. The conflict is that the developer doesn’‘t have time to do all the projects. So you have two approaches, make the developer more effective or give them more time.

The other option is one that requires months of foresite. We have a project starting in May, two weeks from now. It’s not going to happen. I knew it wasn’t going to happen when it was proposed a month and a half ago. I had hoped but I think that in the back of my mind I knew it wasn’t going to happen.

But telling a client you’ll get to their project seven months from now is going to be a hard sell.

Conclusion

Point is, hiring developers is pretty much out. There are two options in our case which are to make the developer better or make the projects farther apart.

There are things blocking both, all we need to do is figure out what the blocks are, which are biggest, and how to deal with them.

Posted in  | no trackbacks

Using Rails to Create a Static Site

Posted by Chuck Vose Thu, 20 Apr 2006 19:04:00 GMT

Overview

A customer of ours has a splendidly restrictive environment which I have the pleasure to work within. Not only is there no Rails, there’s no PHP and presumably no database to hook into even if there were dynamic languages. This is probably complete crap but it led to an interesting problem solving situation regardless.

What do you do with a client that wants hundreds of pages to be redesigned when you don’t have access to handy timesaving tools like Rails or PHP?

Long before I started research I told my boss to continue with the site anyways; I thought that caching would work exactly the way I needed. This turned out to be completely wrong but the site was well underway so I had to figure something out.

After trolling the net for a long time I stumbled on a website that took ASP pages and made static pages out of them by spidering; basically wget tweaked a little bit and resold for far too much money.

So I endeavored to do exactly the same for Rails.

Routing

In order to make this work I knew that I needed to do be able to represent pages by their name; something like activities.html would pull up the page with the title ‘Activities’. Once I had the idea it was a short jump to the following routing rules:

map.connect '', :controller => 'page', :action => 'splash_page'
map.connect ':id', :controller => 'page', :action => 'index'
map.connect ':controller/:action/:id'

The first allows the blank page to be a custom welcome page as is standard for us. The third is the standard route just in case, but the second is the monkey-maker.

I realize now that I could have just made .html but I’ve justified it to myself by saying that the titles make for better presentation.

The Code

The code below is the default action for the controller and essentially fills the spot of the routing code with a couple of tweaks.

The index bases decisions on whether there’s just a number, whether there’s a .html, or just straight text.

def index
  # If there's a number in the id assumed that it's the id of a page.
  if params[:id] =~ /^\d+$/
    @page = Page.find(params[:id])

  # If there's a .html in the id assume we want the page with that title.
  elsif params[:id] =~ /^.*\.html$/
    # This allows users to use any case for the link name.
    # Otherwise exporting to windows/mac might break from
    # multiple pages being named the same. For instance
    # Index.html != index.html in Linux but does in Windows/Mac.
    # Therefore sending both versions will break a
    # lot of archiving utilities in Win/Mac.
    if params[:id] =~ /[A-Z]/
      redirect_to :action => :index, :id => params[:id].downcase
    end
    # Otherwise strip the .html and the _ then query the database.
    @page = Page.find(:first,
                      :conditions => ['title = ?', html_to_title(params[:id])])

  # Finally if theres simply a name we should redirect to 
  # the .html version like we did above.
  elsif params[:id]
    redirect_to(:action => :index, 
                :id => title_to_html(params[:id])
  end

  # If the page somehow makes it through that battery 
  # and the routing rules above just redirect to the 
  # homepage keeping the flash intact.
  if @page.nil?
    flash[:notice] = flash[:notice]
    redirect_to :action => :splash_page
  end
end

Finally there are the helper scripts used above:

def title_to_html(title)
  title.downcase.tr('\ \\\/', '_') + '.html'
end

def html_to_title(title)
  title.gsub(/\.html/,'').humanize
end

Wget

Now that we have pages that are entirely named correctly we can simply use wget to create a perfect copy on her server.

For easy reference I used the following:

wget -m -nH www.example.com

Conclusion

After hours of tweaking I’ve arrived at a very stable and comfortable arrangement. The client knows that pages are simply the name of the page with underscores for spaces and for the most part things are working nicely.

Changing page titles is still a pain and probably always will be. We dealt with this by making a links area above the text which adds some order while solving the interpage problem. I think there are currently only two links in the actual pages that point to a page on the server.

When using wget it’s especially important to make sure that all the links are the same style. For instance having a / in front of some links but not in front of others can lead to weirdness when you’re in a sub-directory and having mixed case will break windows servers (though I’ve attempted to remedy this).

Another caveat is that wget doesn’t follow javascript links, pop-ups, or roll-overs. All pages that can only be accessed through a form or a js action need to be manually copied with the rest of the files.

If nothing this project makes for an interesting comparison in benchmarking. If you were benchmarking the caching ability of a Rails app it would be lovely to see the speed of the straight html as well.

Posted in ,  | no trackbacks