January 2006 Entries

Requirements Considered Harmful

Micah delves into the dark side of requirement documents. I am glad he is taking on writing about some of the challenges we’ve faced in starting a new company. I’ve been planning to write about many of these challenges as well, but I wanted to give myself more time. Perhaps I was a bit too shell-shocked by all the difficulties to give it a proper treatment. Perhaps I was afraid I would violate the one blogging rule we have, don’t be stupid.

Fortunately, Micah has the bravery to delve into the deep dark dirty recesses of real world project management. Read it at your own risk and hold tight to your sanity.

You Could Hit Eight Level Tonight

Basement Gamers Video Screenshot Make some time for this one. This is an eleven minute mockumentary of two hardcore fantasy role playing gamers. If you’ve ever rolled the icosahedron1 dice (or live with someone who has), you’ll find this extremely funny, and perhaps painful.

I swear I was never this bad. Really.

Watch it if you dare.

[Via The Old New Thing]

1 icosahedron is 20-sided.

The Team Grows

A while ago I told you that I was starting a company with my business partner, Micah. Well the good news is that we’ve officially added another partner/employee, the indefatigable Jon Galloway.

In the link to Micah breaking the news, he says he is really glad our clients don’t pay us to look pretty or we’d be broke. He can speak for himself, because if he read the fine print on the contract I’m working on, being pretty is indeed one of the requirements.

Is It A Hate Crime If It Happens In An Online Game

This article in Boing Boing about how World of Warcraft (WoW) moderators are warning groups not to adverties their guilds as “GBLT-friendly” (Gay, Bi-sexual, Lesbian, Transgender friendly) got me thinking.

Suppose they allow characters in WoW to publicly declare their sexuality within the game. Now suppose other groups within the game form with the goal of attacking such players completely within the online game (assuming the game allows players to attack other players).

Would that constitute a hate crime?

Dynamic WHERE and ORDER BY Without Dynamic SQL

My friend Jeremy (no blog) pointed me to these two useful articles on how to perform dynamic WHERE clauses and ORDER BY clauses without using dynamic SQL. These were written long ago, but I had never thought to use COALESCE in this way. Very cool!

I will post them here so I can find them later.

UPDATE: This technique may not be as performant as hoped for. Marty in the comments noted that he saw table scans in using COALESCE in this way. Jeremy showed me an example that demonstrated that the execution plan changed from an index seek to an index scan when using COALESCE. As always, test, test, test before rolling this out.

Technorati Tags: ,

Who Owns the Copyright for An Open Source Project

This is part 3 in this series on copyright law and open source licensing. If you haven’t already, consider reading Part 1 and Part 2 of this series for background before tackling this topic.

To properly license open source source code, the license agreement must be included prominently with the source code. Many simply put a license.txt file in the root of the source tree and publish the license on their project website. Others take the extra step to include the license text in a comment within every source file.

Assigning Copyright

Take a look at the license for DotNetNuke (DNN), a very popular open source portal software for the .NET platform. In particular note the very first section:

DotNetNuke® - http://www.dotnetnuke.com
Copyright (c) 2002-2005
by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )

Notice that Perpetual Motion Interactive Systems Inc. owns the copywrite to the DotNetNuke codebase. “How can that be? How can a corporation own the copyright to code that is open source?” you might ask. Don’t worry, there is nothing sinister going on here.

In part 1 of this series I stated that when you write code, you own the copyright to it (with a couple of exceptions such as work for hire). However, imagine the logistical and legal nightmare if everyone retained the copyright to code contributed to an open source project, especially if some decided to choose their own compatible license. The source code would be littered with copyright statements and license files for every contributor.

Instead, it is usually the policy for an open source project to assign copyright to a single legal entity or person. Keep in mind that although this person then owns the copyright, the code has been released under a license that allows free distribution. Thus the fact that the copyright has been assigned to an individual entity does not make the code any less open.

For example, suppose Perpetual Motion decides they want to exercise their copyright and make a proprietary version of DotNetNuke. They certainly have the right to do so, but they cannot stop others from freely viewing and distributing the code under the pre-existing license up to the point at which they close the source. At that point, contributors would be free to fork the project and continue development under the original license as if nothing had occured.

Copyright Assignment Policy

According to a lawyer Fogel talked with...

For most, simply getting an informal statement from a contributor on the public list is enough—something to the effect of “I hereby assign copyright in this code to the project, to be licensed under the same terms as the rest of the code.”

Is sufficient. Some organizations such as the Free Software Foundation, on the other hand, apply a very formal process requiring users to sign and mail in paperwork.

In any case, some open source projects do not have such a copyright assignment policy in place, but it makes sense to do so. As Fogel points out, should the terms of the copyright need to be defended, it is much easier for a single entity to do so rather than relying on the cooperation of the entire group of contributors, who may or may not be available.

Having the copyright assigned to a corporation also protects individual developers from exposure to liability in the case of a copyright infringement suit.

I Swear

If Visual Studio .NET 2003 completely crashes during one more debug session in the next hour (I need to be reasonable here), I am going to throw my freaking computer through the window (figuratively speaking).

Thanks for letting me vent.

Developers Guide To Open Source Software Licensing

This is part 2 in my series on copyright law and software licensing. Part 1 covered the basics of copyright law. With the background knowledge from that post, we are ready to tackle software licensing in more depth.

Licensing In General

A license is permission granted by a copyright holder to others to reproduce or distribute a work. It is a means to allow others to have some rights when it comes to using a work without assigning the copyright to others.

For example, although I own exclusive copyright to this very blog post, at the bottom of every page in my blog I provide a license to freely copy, distribute, display, and perform the work. I also allow making derivative works and commercial use of the work under a Creative Commons license. Gee what a nice guy I am! However I do stipulate one restriction. Anyone who wishes to exercise one of the listed rights within the license must attribute the work to me and make clear to others the license terms for the work. As the copyright holder, I am free to grant others these rights, but also to add restrictions as well.

Proprietary and Closed Source Licenses

Copyright law and licensing applies to software every bit as much as it does to writing. Most of the software that the average person uses day to day falls under a proprietary license. That is, the user is not free to distribute the software to others. This is often called “closed source” software, but that term may be slightly misleading as software can have its source code visible, but still not allow open distribution. Likewise, it is possible for closed-source software to allow others to freely distribute it as in the case of many free utilities.

Open Source and Free Software Licenses

This leads us finally to “Open Source Software” and “Free Software”. The two terms are often used interchangeably, but there is a slight distinction. The term “Free Software” tends to apply to software licensed in such a way that any code that makes use of the free software code must itself be freely available. The “free” in “Free Software” applies to the freedom to view the code.

Whereas “Open Source” is a more blanket term that merely applies to software in which the source code is visible and freely distributed. Open Source software does not necessarily require that its usage also be Open Source. Thus Free Software is Open Source, but Open Source is not necessarily Free Software.

Types of Open Source Licenses

When starting an open source project, the copyright owner is free to license the source code to others in any manner he or she sees fit. But the cost to draft a custom open source license is prohibitive. And to do so oneself is often a big mistake, especially given the fact that there are many well established licenses in existence that have stood the test of time.

Choosing A License

The Fogel book does a decent job of providing insight into how to choose a license, so I won’t delve into it too deeply.

GPL

Despite the plethora of licenses, in general the one you choose will be a result of your philosophical disposition towards open source software. If you fall under the free software camp and believe that all software should be free, then you may gravitate towards The GNU General Public License (GPL).

The GPL is designed to guarantee the user’s freedom to share and change the software licensed under its terms. When using GPL code, no additional restrictions may be applied to resulting product. In this way, the GPL is similar to the Borg. If you wish to use GPL code within your own project, then your own project must be licensed in a compatible manner with GPL. Thus GPL code tends to begat more GPL code. It is not permissible under the GPL to use GPL in proprietary software while keeping that software closed source.

MIT and BSD Licenses

For others with no philosophical objection to using open source software within proprietary software, the MIT license or the new BSD license may be more appropriate.

In essence, these licenses do not provide any restrictions on how the software may be copied, modified, or incorporated into other projects apart from attribution. Thus you can take code from a BSD licensed project and incorporate it into your proprietary software. You can even try to sell BSD licensed software as is (technically you can do this with GPL too), but this is as difficult as selling ice to Eskimos. Because you cannot restrict others from simply obtaining the source code, selling open source licensed software as is makes for a difficult proposition. You had better add a lot of value to be successful. Popular .NET projects such as Subtext, DasBlog, and RSS Bandit are all licensed under the BSD license.

Stay Tuned for Part 3.

The Developer's Guide To Copyright Law - Part 1

Disclaimer

Book Cover As is customary when a non-lawyer attempts to discuss the finer points of the law, I must start with a disclaimer. I know some fine lawyers, but I, sir, am not a lawyer. So please do not consider this to be legal advice. It is merely a rough primer on copyright law as it pertains to software based on my readings and conversations. If you need specific legal advice, talk to your own lawyer.

Intro

After finishing the Fogel book, “Producing Open Source Software”, I followed up by reading “Understanding Open Source and Free Software Licensing” by Andrew M. St. Laurent.

This book combined with previous readings serves as the inspiration and source for this series. I will focus on the issues pertinent to software developers who wish to get involved in open source development. For a more complete treatment of the topics, I recommend reading the books mentioned.

In this first post in this series, I will discuss the basics of copyright law. This will set the stage for part 2 in which I will discuss software licensing.

Basics of Copyright

As soon as you set pen to paper, brush to canvas or fingers to that dirty keyboard, the work you create is automatically afforded protection by copyright law. This assumes that your creation is not itself infringing on another’s copyright as in plagiarism. Also, there must be a small degree of creativity in the work. For example, you cannot simply jot down and copyright names copied from a phone book. Additional copyright protection is available through registration with the copyright office.

Note that copyright applies to a particular expression of an idea, not to the idea itself. You can copyright a specific drawing of a penguin, but your copyright does not apply to drawings of penguins in general. Trademarks and patents are used to provide legal protections for concepts, ideas, facts outside of the scope of copyright law, but that is a topic out of scope for this post.

The Rights of Copyright

So exactly what rights do you have to copyrighted works? Well the obvious right is the right to copy. A copyright gives the owner full and exclusive rights to control who may copy or create a derivative of a work and how that may be done. As a copyright owner, you may state that nobody is allowed to copy or make derivative versions of your work (though the doctrine of “fair use” allows some non-infringing uses such as quoting from the work in a book review). A copyright gives the owner exclusive rights to a work, but this protection does not last forever.

If someone were to infringe on your copyright, you have the right to sue for damages, but this requires that you prove a loss occurred due to the infringement, which can be difficult. You may receive additional copyright protection by registering the work with the copyright office. For example, you can get “statutory damages”, compensation fixed by law that does not require proving an actual loss.

Who Owns Your Code?

Therefore you own the copyright to every line of code you write. Well... sort of.

The code a developer writes while an employee or client fall under the doctrine of “work for hire” and therefore belong to the employer (or client). Some independent contractors will stipulate in their service agreement with the client that even though the client owns the copyright to the code, the client shall give the contractor a non-exclusive license to the code.

Next Time: Licensing

In the next post in this series, I will discuss licensing and get into the nitty gritty as it pertains to open source software. Many thanks to my friend Walter Impert for his legal editing.

I Won The Lottery!

Well today completes my 31st trip around the Sun and what a Birthday weekend it has been! Every now and then I like to buy a Super Lotto ticket just for the fun of it. I have a solid understanding of math (I did major in it) and I know that the odds are pretty much zilch, but it is fun to think about what I would do should I win.

Well I can stop thinking and start doing because I did win! I matched three number and the MEGA for the Jan 18 drawing winning me a grand total of $47.00! Woohoo! Forty-seven smackeroos! I definitely will NOT spend it all in one place (unless I fill up on gas). Since it is a jackpot under $600, I can simply walk over to the store where I bought it and claim my prize.

Apart from the Super Lotto, this weekend reminds me that I have won many other lotteries in life. Saturday we had some friends over for a birthday party at our place and it is quite clear that I have won the lottery of friends. My wife organized the whole thing and cooked up an amazing curry. I have definitely won the lottery of wives. And yesterday, in the opening game for my soccer league, I had an assist and I scored a pretty sweet goal in the first 60 seconds of the second half, winning the lottery of...er...that game four to nill. Ok the lottery analogy has fallen apart.

To you that find this post, I hope you win the important lotteries in your life as well.

Best Blonde Joke Ever?

I know I am a bit late to this, but seriously, I have to link to this. This is the best blonde joke ever.

Rumor has it I was blond once, at least for the first year of my life. No wonder all I could do was dribble all over myself.

Granting Commit Access to Open Source Projects

Every open source project has its own procedures for granting the all-important commit access to developers. Some require a set number of submitted patches (which Fogel, author of Producing Open Source Software, warns against). Others do not have any clear process and rely on the whims of those with the ability to add other committers. Whichever procedure your project chooses, it is important make sure make sure it is clearly published in a visible location such as in the developer guidelines.

Fogel discusses the methods by which the Subversion project grants commit access.

In the Subversion project, we choose committers primarily on the Hippocratic Principle: first, do no harm. Our main criterion is not technical skill or even knowledge of the code, but merely that the committer show good judgement. Judgment can mean simply knowing what not to take on. A person might post only small patches, fixing fairly simple problems in the code; but if the patches apply cleanly, do not contain bugs, and are mostly in accord with the project’s log message and coding conventions, and there are enough patches to show a clear pattern, then an existing committer will usually propose that person for commit access. If at least three people say yes, and no one objects, then the offer is made. True, we might have no evidence that the person is able to solve complex problems in all areas of thecode baes, but that does not matter: the person has made it clear that he is capable of at lest judging his own abilities. Technical skills can be learned (and taught), but judgement, for the most part, cannot. Therefore, it is the the one thing you want to amke sure a person has before you give him commit access.

Obviously, one problem with this approach for very small projects is you might not even have three committers. This merely reinforces the fact that any policy should fit the size of the project and should be amended as the project grows. But its emphasis on judgement as opposed to technical skill is, in my opinion, a good one.

On any project, there will always be plenty of small tasks that do not require Linus Torvalds to get it done. Rather they can be handled by Joe Hobbyist and Jill N00b, as long as they exercise good judgement. And having someone focused on these smaller easy tasks helps the overall polish of the application, as the "serious" developers often do not spend their time on them.

Another benefit of this approach is that it does not rely on an artificial quota, but on recognition by other committers that someone exhibits good judgement. Ostensibly, if the other committers were chosen because of their good judgement, they can most likely be trusted to use good judgment when recommending and voting on other committers.

I recommend reading the book to delve into the actual procedures for handling the voting and making the offer.

XHTML Conformance in ASP.NET 2.0

The key purpose of my last post was to demonstrate how the ASP.NET web controls follow the Decorator pattern when it comes to rendering and how developers can hook into that to customize the rendered HTML.

The example I demonstrated made a Button control render XHTML conformant markup. My article applies to ASP.NET 1.1. However, one commenter pointed out an even easier approach if you are working with ASP.NET 2.0. You can simply set the xhtmlConformance elment in Web.config. For example:

<xhtmlConformance mode="Transitional"/>

Well, I am sure you’ll find other uses for the decorator technique I wrote about.

Using a Decorator to Hook Into A WebControl's Rendering for Better XHTML Compliance

Man! What a mouthful of a title, but I think it succinctly describes what this post is about. I will demonstrate how to hook into the rendering of a control that inherits from System.Web.UI.WebControls.WebControl using a Decorator. In particular, I am going to hook into the rendering of a Button control to stop it from emitting the language="javascript" attribute.

Why?

Because I am a bit anal about XHTML compliance. The Button control renders an input tag with the language attribute. But according to the XHTML 1.0 transitional spec, this is an invalid attribute.

More than just being anal, I also thought it would serve as a nice demonstration of this technique in case you want to build custom controls that modify the rendering of other controls just slightly without having to rewrite a lot of code.

First Naive Attempt

My first attempt to handle this was to simply try and remove the language attribute via the following code placed in the OnPreRender method of my page:

btnSubmit.Attributes.Remove("language");

That didn’t work because the button control doesn’t explicitly add the language attribute to the attributes collection. Instead, the attribute is added within the Render method which is called by the page when it is time for a control to render its contents to HTML.

Examining The Rendering Process

The Render method is passed an instance of HtmlTextWriter used to render the page. One of the methods on this class is AddAttribute which has several overrides. Using Reflector I found that the method that adds the language attribute has the signature AddAttribute(string name, string value);.

The Decorator

Now if only I had some way to override that method to discard attributes with the name “language”. That’s where the decorator pattern comes in.

The class I want to decorate is the HtmlTextWriter. Fortunately the authors of this class did a good job of making it extensible and easy to decorate. HtmlTextWriter has a constructor that takes in an instance of TextWriter. Methods on the HtmlTextWriter use the specified TextWriter to write to the underlying stream. The good news is that HtmlTextWriter inherits from TextWriter. So if I want to hook into the rendering process, I just need to implement my own HtmlTextWriter and override the specific methods I need.

The CompliantButton class

The first step is to create a CompliantButton class that inherits from Button. Within that class I created a private internal class named CompliantHtmlTextWriter like so:

private class CompliantHtmlTextWriter : HtmlTextWriter

{

    internal CompliantHtmlTextWriter(HtmlTextWriter writer) : base(writer)

    {

    }

 

    /// <summary>

    /// Ignores the language attribute for the purposes of a submit button.

    /// </summary>

    public override void AddAttribute(string name, string value, bool fEndode)

    {

        if(String.Compare(name, "language", true, CultureInfo.InvariantCulture) == 0)

            return;

        base.AddAttribute (name, value, fEndode);

    }

}

This is the decorator. Notice that the constructor takes in another HtmlTextWriter which it will forward method calls to. The AddAttribute method simply forwards calls to the base class unless the attribute name is “language”.

Redecorating

Now all that is left is to use the decorator within the render method of the CompliantButton class. Here is the render method:

protected override void Render(System.Web.UI.HtmlTextWriter writer)

{

    base.Render(new CompliantHtmlTextWriter(writer));

}

Notice that I am wrapping (decorating) the HtmlTextWriter parameter with my CompliantHtmlTextWriter decorator before passing it along to the base Render method. As far as the base Render method is concerned, it is dealing with an HtmlTextWriter. It doesn’t need to know any specifics about the decorator class. But via decoration, the behavior has been slightly modified. No more language attribute.

A Word to the Wise About Spam Filters

Cash Money If you are going to talk about a product named “Microsoft Money” you had better make sure your comment spam filter doesn’t barf on the word “money”. That just wouldn’t be nice to the helpful people with legitimate comments.

My apologies to those who were frustrated by my blog puking on your well intentioned comments. I had previously assumed nobody had a good reason to comment me abount money. But then I started talking about it. Eeeediot!

Frustrated With Microsoft Money

I really appreciate how Microsoft has really opened up many of its internal developer groups. I only wish this also applied to more of their consumer products.

For example, I am trying to set up online services for a bank within Microsoft Money. My bank allows passwords up to 32 characters. Microsoft Money allows me to enter 8 characters and that’s it. WTF!? With all this emphasis on security, you’d think they would support more than 8 characters in a password, especially when the bank does.

So I try going to the support site and there is nothing helpful. Since my copy is over a year old, I get the lovely option to pay $35.00 for a support incident. Heck for that money, I might as well upgrade, but how do I know this problem is even fixed in the latest versions? I don’t.

So following the support instructions, I head over to the Microsoft Money community newsgroups to be greeted with the message...

Service Temporarily Unavailable

We apologize for this inconvenience. Please try again later.

Great! It appears there is no way for me to register a complaint or have someone tell me whether this is fixed in the latest version of Money for this institution. Maybe I should have bought Quicken.

Setting Up CVS Commit Emails In SourceForge

One key component of open source projects is getting others involved in code review. In fact, that has always been one of the promises of open source software that with the hundreds and thousands of eyeballs looking at the code, the quality will be higher. In practice this doesn’t necessarily work out because the majority of open source projects only have a few eyeballs at work.

Also, in order to get those eyeballs reviewing code, the bar of entry must be low. Requiring users to set up CVS and track commit logs is a major hurdle. That’s where commit emails come in. Commit emails are triggered by a commit to the source code repository and typically contain the log message of the commit, which file or files were changed, and a diff of the changes.

Having others review commit emails also keeps people honest in their log messages and provides a means to help propagate and support project standards.

Originally I intended to generate an RSS Feed for commits, but I found that the approach I was taking was impossible in SourceForge. SourceForge does not allow writing to the Web Shell Services from scripts running within CVS. However, I have another idea brewing that won’t require file write access to the shell web services, but I#&8217;ll need to brush up on Python first.

Sourceforge uses CVS syncmail for sending out email notifications of commits within CVS. Each email provides the log message and a diff (an example is at the bottom).

Setting this up is pretty well described by the documentation. The only thing I have to add is that to checkout the CVSROOT module, follow the same instructions for checking out the project’s main module as I wrote in the past , but enter "CVSROOT" for the Module name at the bottom of the TortoiseCVS dialog.

This is currently set up for Subtext (click here if you wish to subscribe).

Example of a commit message

Update of /cvsroot/subtext/CVSROOT
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11754

Modified Files:
	loginfo
Log Message:
Changing the comment for the purpose of testing commit emails.

Index: loginfo
===================================================================
RCS file: /cvsroot/subtext/CVSROOT/loginfo,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** loginfo	16 Jan 2006 17:02:50 -0000	1.7
--- loginfo	16 Jan 2006 17:07:31 -0000	1.8
***************
*** 27,33 ****
  #DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
  
! # This line sends all changes to the CVSROOT module to the user specified ! # by USERNAME. It is recommended that someone be watching this module ! # as it shouldn't need to be modified very often.
  CVSROOT /cvsroot/sitedocs/CVSROOT/cvstools/syncmail %{sVv} haacked@users.sourceforge.net
  
--- 27,32 ----
  #DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
  
! # This line sends all changes to the CVSROOT module to the specified email address.  
! # This module shouldn't need to be modified very often.
  CVSROOT /cvsroot/sitedocs/CVSROOT/cvstools/syncmail %{sVv} haacked@users.sourceforge.net
  

Misperceptions of Open Source

Tim Bray writes to correct misperceptions of what “Open Source” is about.

They both paint a picture of misguided innocents who believe in some starry-eyed vision of post-capitalist intellectual collectivism, but are actually pawns in the hands of larger economic forces. They’re both really wrong. Granted: Open Source is not a nation or a corporation or a political party or a religion. (While there are “movement people”, organized into the skeptical-of-each-other Open Source and Free Software sects, they are a tiny—albeit noisy—minority.) Absent those things, what is left? A collection of people who like working on software and actively seek out opportunities, preferably but not necessarily paid, to do so. If that is isn’t a “community”, what is?

Tim hits it on the mark. If Subtext is a pawn in some larger economic force, I’d be curious to find out which major corporate power seeks to gain, and perhaps ask them for some funding. ;)

In truth, there are many reasons people work on open source software, and they are not all the same. Many just find it fun to work on something more interesting than the boring data-in data-out systems they build at work. Some want to have a hand in building a better mousetrap. Many enjoy participating in a community and perhaps gaining a bit of recognition among their peers. A few see it as a political movement against capitalist interests. Yet others are paid to work on open source projects as it benefits their employer. None of these reasons are inherently wrong, misguided or amoral.

Many of these articles criticising open source focus on the big projects. What they fail to look at is that the majority of open source projects are very small. Many fill very niche markets that corporations have no interest in filling, but that there is yet a long-tail demand for.

Running An Open Source Project

Producing Open Source Software Cover I just finished reading the book "Producing Open Source Software - How to Run a Successful Free Software Project" by Karl Fogel (pdf available). CollabNet has employed Karl Fogel for the past five years to work on Subversion. Prior to that he has been involved with GNU Emacs and CVS development.

If you fall in one of the following categories, I highly recommend taking the time to read this book. Especially if you fall in one of the first two.

  • Planning to start an open source project
  • Currently running an open source project
  • Involved with an open source project
  • Managing a team of distributed developers

Much of this book is really a primer on how to work with and manage people. After all, open source development is really built on relationships more than even technical know-how. Manage the relationships well, and people will happily contribute. Do a poor job, and you may find interest lacking (though interest may lack for many other reasons as well).

But Fogel also delves into how to structure a project and administer the day-to-day activities that are required to run a project smoothly. Some of the topics he covers include:

  • How to choose a license
  • Who to give commit access to
  • Writing Developer Guidelines
  • Hosting and choosing version control
  • Managing communications
  • Assigning roles
  • Voting

And the list goes on.

It is my hope to start applying some of the principles he writes to open source projects I am involved with such as Subtext. Though Fogel’s experience and advice seems targetted to very large open source projects, I think much of it is useful for small projects as well. Besides, if you don’t prepare for growth, you will never see growth. And if you do grow big suddenly, it is better to be prepared than caught off-guard. But having said that, it is also important to adjust the level of formality in processes and structure to agree with the size of the project. So I won’t let myself get carried away.

Instead, I hope to start a short blog series to summarize and perhaps expand on certain principles gleaned from the book.

Quickstart Guide To Shell Services In SourceForge

Consider this a more advanced followup to my Quickstart Guide to Open Source Development With CVS and SourceForge.

Intro

So you have finally decided to become a flower power card carrying community loving member of an an open source project that happens to be hosted on Sourceforge. Good for you! Unfortunately, someone might expect you to actually contribute something. Suppose they give you the responsibility to update the project Home Page. SourceForge provides the ability to host project home pages within SourceForge itself, but how do you access those files? This guide will help you with that so you can earn the respect of your peers and graduate from n00b to contributor.

First, it is important to understand that you will not be able to fallback on your trusty FTP client to move your files to your SourceForge website. If you are a Windows developer unnaccustomed to the *nix-y ways of doing things (*nix == unix, linux, anyothernix...), it’s time to get the hands a bit dirty. But don’t you worry, I’ll present the most Windowsy manner to get *nixy tasks done.

To access files on SourceForge, you are going to have connect to their shell services via an SSH session. SSH is a protocol which is analogous to, but different from FTP. Some applications adopt this protocol to provide secure communication between servers, such as SFTP (secure FTP) and SCP (secure copy). Applications which are not built on SSH can still use these services by communicating through an SSH tunnel.

WinSCP To Securely Transfer Files

The quick and easy way to do this for those of us who don’t work with *nix every day is to download and install WinSCP. WinSCP is both a SFTP (SSH File Transfer Protocol) and SCP (Secure Copy Protocol) client.

SourceForge Project Shell Info

Before you start with WinSCP, you’ll need some information about your SourceForge project handy. Remember, as with all things *nix, everything is case sensitive.

  • Hostname: shell.sourceforge.net (or shell.sf.net)
  • Username: as used to login to the SourceForge.net web site.
  • Password: Password authentication is not supported. You must configure a SSH key pair for authentication.
  • Project Group Directory: /home/groups/P/PR/PROJECTNAME
  • Project Web Directory (root): /home/groups/P/PR/PROJECTNAME/htdocs
  • Project Web CGI Script Directory: /home/groups/P/PR/PROJECTNAME/cgi-bin

For example, these values for me on Subtext are...

  • Hostname: shell.sourceforge.net (or shell.sf.net)
  • Username: haacked
  • Password: leave blank
  • Project Group Directory: /home/groups/s/su/subtext
  • Project Web Directory (root): /home/groups/s/su/subtext/htdocs
  • Project Web CGI Script Directory: /home/groups/s/su/subtext/cgi-bin

Using WinSCP

When WinSCP first starts, you will see a dialog box that requests various host information. Enter the following details in to the provided dialog box:

  • Host name: shell.sourceforge.net (or cf-shell.sourceforge.net)
  • Port number: 22
  • User name: YOUR_USERNAME
  • Password: leave this field blank
  • Private key file: Click on the "..." button to browse for the PuTTY private key you created previously following the instructions here. Load the desired key.
  • Protocol: SFTP (allow SCP fallback)

Below is a screenshot of this dialog and how I entered the fields.

Click Save and choose the default for the session name which should matche the hostname you entered previously (USERNAME@shell.sourceforge.net or USERNAME@cf-shell.sourceforge.net).

To start the session, click the Login button. The first time you do this for a session, you will get a dialog asking to compare the SSH host key fingerprint. This is to make sure you are connecting to the site you think you are connecting to.

If you followed the instructions as I described, you should see the following key:

4c:68:03:d4:5c:58:a6:1d:9d:17:13:24:14:48:ba:99

If yours differs, compare it against the list of keys here. If it does not match, please contact SourceForge.net staff by submitting a Support Request.

Once you are logged in, you can browse your project directories. Browse to your project root and if you choose the Explorer view as I did, it should look like the screenshot below.

WinSCP ScreenShot

Place your web files within the hcp directory. Unfortunately at the time of this writing, SourceForge won’t run .NET code, but it does support cgi as well as PHP and MySQL.

References

Vista Could Be So Much Better

Vista From reading other blogs, it seems many developers are unimpressed with the sheen of Windows Vista, the next version of the Microsoft operating system. There is definitely appreciation for all the improvements under the hood, but the out-of-box experience (at least in the betas), leaves much to be desired.

That is why I love this post from Jon Galloway that first points to some videos that compare Vista to Mac OSX (released 2002). He then lists several ways that Microsoft could inexpensively do better. My favorite quote is this...

...you've got Paint.NET, which stomps MS Paint so badly I have to turn my head away and sob.

Setting Up Log4Net For Multi Layered Applications

A while ago I wrote up a Quick and Dirty Guide to Configuring Log4Net for Web Applications. Today I received an email asking how to set up logging for a web application that also consists of a business layer and a data access layer.

The Situation

This person had the following three projects setup as part of his VS.NET Solution:

  • ASP.NET Web Application Project
  • Business Layer Class Library Project
  • Data Access Layer Class Library Project

Note that the Web Application project has a project reference (or assembly reference) to the Business Layer, which in turn probably has a project reference to the Data Access layer. These assemblies will be deployed with the web application and will not be hosted on separate servers, thus remoting does not come into play here.

The developer added a Log4Net.config file to each project as well as the AssemblyInfo directive described in my post. The goal was to get all three projects logging to the same file. For the two class library assemblies, the developer specified the full system path to the log file.

The Explanation

To understand why this doesn’t necessarily work, we have to step back and look at how configuration settings are picked up by a .NET application in general. Suppose we were’t dealing with Log4Net for a second, but wanted to configure some app settings? Would it require that we add an App.config file to the Business Layer and Data Access layer project? Indeed no. These are class libraries. They do not contain an execution entry point as an executable does. We simply need to add a web.config file to the Web Application Project and we’re set.

The main reason for this is that configuration settings apply to the executable application (in this case a web app). You can certainly include code within the business layer assembly to read app settings, but it reads the settings from the web.config or App.config file in the execution startup path.

Note: I am doing a bit of hand waving here. Technically, the ASP.NET web application assembly is not an executable, it is a class library. However due to how the ASP.NET runtime works, it exhibits some of the behavior of being an executable and for the purposes of this discussion we’ll leave it at that. One key difference though is that for executables, the config file must be named the same as the assembly with a config extension and put in the same directory as the executable (typically bin), whereas with an ASP.NET application, the config file is always named “web.config” and placed in the web root, not in the bin directory.

This is also how Log4Net configuration works. Remember that when you build the web application, your business layer and data access layer assemblies will be copied to the bin directory of the web application. Thus all three assemblies are in the same location, so there is no need to specify a different Log4Net.config file for each assembly.

When you think of it, this makes sense. Your business layer assembly is a class library, thus it can be used and re-used in more than one project. It is not an execution starting point, but is called into by another executable. You wouldn’t want that assembly to specifiy where it logs its messages. You would rather have the consumer of the assembly do that.

The Answer

So the answer to the question is to make sure that both the business layer and data access layer projects do NOT include a Log4Net.config file nor the AssemblyInfo directive. They do not need it. It will be up to the consumer of these assemblies (the execution starting point) to configure logging.

All you need to do in these assemblies is to add an assembly reference to the Log4Net assembly and make calls to its logging methods in your code just as you would in the web application layer.

Then configure your web application as mentioned in my dirty guide and you are all set. Log messages from all three assemblies should funnel nicely to your log file.

To demonstrate this, I set up another sample VS.NET 2003 solution. It is based on the same project that I included in my previous article on the subject, but includes a business layer class library. The web application references the class library and makes a method call that logs a message. The class library references Log4Net, but does not include the Assembly directive nor the Log4Net.config file.

Download it, set up the IIS directory, and visit the default page. You’ll see log messages from within the business layer as well as the web application in the log file.

Clickable Background Images Via CSS

On a recent project, my team pursued a CSS based design as we had two sites to build that were similar in layout, but different in look and feel. We were brought in after the schematics and design had pretty much been worked out, but we felt we could work with the agreed upon design.

The site had a typical corporate layout: a header, a body, and a footer. The body might have two or three columns. We started off writing markup that had a structure like so (not including the body columns).

<div id="main">
    <div id="header">
    </div>
    <div id="body">Body</div>
    <div id="footer">Footer</div>
</div>

We set the logo using CSS by applying a background image to the header div.

#header
{
    background: url(logoExample.jpg);
    width: 180px;
    height: 135px;
}

Which produces something that might look like this (Trust me, the real thing looks a lot better)...

So everything is fine and dandy till we place the site on a staging server and the client asks that the header logo link back to the main page. This wasn’t in any of the requirements or design spec, but it is perhaps something we could have guessed as it is quite common.

So how do we make the logo image be a clickable link to the main page? My first inclination was to abandon using a background image and make the logo a regular image. The markup would look like (changes in bold)...

<div id="main">
    <div id="header">
        <a href="/"><img src="images/logoExample.jpg"></a>
    </div>
    <div id="body">Body</div>
    <div id="footer">Footer</div>
</div>

But I found a better way to do this based on a technique I saw in “Bulletproof Web Design”. I changed the markup to be like so...

<div id="main">
    <div id="header">
        <a href="/" title="Home"><h1>Title</h1></a>
    </div>
    <div id="body">Body</div>
    <div id="footer">Footer</div>
</div>

I then changed the css for the anchor tag to have the same dimensions as the logo image. I positioned it so that it would fit exactly over the image.

#header
{
    background: url(logoExample.jpg);
    width: 180px;
    height: 135px;
    position: relative;
}
 
#header a
{
    position: absolute;
    top: 0;
    left: 0;
    width: 180px;
    height: 135px;
}
 
#header a h1
{
    display: none;
}

Notice that I had to add "position: relative;" to the header element . That ensures that the absolute positioning applied to the header link is relative to the header and not the entire document.

Now the header logo image appears to be a clickable link. Problem solved. I am pretty sure that others have pioneered this trick, but I hadn’t seen anything written up. What I read applied to making clickable tabs.

UPDATE: As Klevo mentioned in the comments, I really shouldn’t have an anchor tag without any text. Including text would be good for search engine optimization and for those who view the site without CSS. Shame on me, especially after reading the bulletproof book.

But to my defense, it was peripheral to the main point I was making. However that doesn’t excuse it as bad samples have a way of proliferating. So I corrected the sample above. The anchor tag now includes the title of the blog, but sets the title to be invisible.

Web Based IM with Meebo

Can’t use your favorite IM tool because of a pesky firewall at your place of work? Kyle points me to this web app, Meebo which appears to be in the alpha phase, but worked fine for me. It allows you to sign in to one of several popular IM services and use a rich web-based client.

So if your worksite allows you to browse the web, you can also chat.

Here’s a screenshot of a section of the login page.

Login Screen

According to the site, passwords are encrypted with 1024-bit RSA keys. Below is a screenshot of a Yahoo Messenger session. Notice the nice transparent effects when highlighting a profile.

Meebo in action

CSS URL References And URL Rewriting

I can get a bit overboard with my virtual paths. I tend to prefer virtual paths over relative paths since they feel safer to use. For example, when applying a background image via CSS, I will tend to do this:

body

{

    background: url('/images/bg.gif');

}

My thinking was that since much of the code I write employs URL rewriting and Masterpages, I never know what the url of the page will be that references this css. However my thinking was wrong.

One problem I ran into is that on my development box, I tended to run this code in a virtual directory. For example, I have Subtext running in the virtual directory /Subtext.Web. So I end up changing the CSS like so:

body

{

    background: url('/Subtext.Web/images/bg.gif');

}

Thus when I deploy to my web server, which is hosted on a root website, I have to remove the /Subtext.Web part. Now if I had read the CSS spec more closely, I would have noticed the following line:

Partial URLs are interpreted relative to the source of the style sheet, not relative to the document.

Thus, the correct CSS in my case (assuming my css file is in the root of the virtual application) is...

body

{

    background: url('images/bg.gif');

}

Now I have true portability between my dev box and my production box.

It turns out that Netscape Navigator 4.x incorrectly interprets partial URLs relative to the html document that references the css file and not the css file itself. Perhaps this was where I got the wrongheaded notion embedded in my head way back in the day.

Mini-Burning Man

Pic of miniature portapotties with superhero figurines next to real portapotties

This photo was taken next to some portapotties that were close to our campsite. I hadn’t noticed these little guys.

Pimp My Desktop

Pimped Desktop Ryan Farley gives the lowdown on his tricked out desktop.

In the past I’ve tried to get into tricking out the desktop, but everytime I switched to a new computer, I felt less and less inclined to do invest the time. Besides, I remember some of these programs would slow down the OS. I like my desktop to be lean and mean.

But after seeing Ryan’s screenshot, I may have to consider playing around with some of the customizations.

It’s funny to me how many geeks I know would dread spending time selecting drapery and customizing the small details of their house (“Pick any color, honey. I don’t care.”) yet will obsess over every pixel of their desktop.

I Must Be Trustworthy

Link Jon Galloway has an interesting write-up on the latest changes to Google’s search algorithms code named “Jagger”

The short and sweet summary is that rather than letting websites “vote” on a page’s relevancy with a link, the trustworthiness of a page is taken into account. For example, a site that has been around longer is potentially considered more trustworthy (assuming it meets other criteria). A page that has incoming links from trustworthy sources is itself more trustworthy.

I had always thought that this was how the PageRank algorithm worked all along. After all, the Google boys original inspiration was the network of citations in academic papers and texts. A citation from a well-cited and trustworthy source boosted the respectability of the cited paper, whereas a citation from a nobody, didn’t account for much.

In the end, I am pretty happy about these changes as my ad-sense revenue has increased lately.

Ego Surfing

Looks like there is a new tool to add to the vain blogger’s utility belt.

Saw this on Scott Hanselman’s blog, who by the way has a HUGE ego. ;)

My ego is still within the terrestial range.

Book Review: Bulletproof Web Design

As I mentioned in my last post, my redesign was inspired by some of the lessons in this book, “Bulletproof Web Design by Dan Cederholm”.

The main focus of this book is how to use CSS and semantic (X)HTML markup to create flexible websites. By flexible, the author is referring to a web site’s ability to deal with the different ways a user may choose to view a site. For the most part, he covers how to make your site more accessible.

For example, many sites do not deal well with the change caused by a user resizing the text. Some sites do not deal well with this, totally breaking the design. If you specify font sizes in pixels for example, IE won’t allow text resizing at all, which gives the designer control, but at the cost of accessibility for those with high resolution monitors or poor eyesight.

Cederholm instructs the reader on several ways to make sites deal with text resizing in a more flexible manner while retaining control. For the most part though, the designer has to give up pixel perfect control in exchange for a better user experience.

The book also delves into accessibility tips such as making sure the sight is readable when images are turned off and when CSS is turned off for those with slow connections or using text to speech readers respectively.

Each chapter presents a sample of a website design that is not flexible. Most of the samples come from real-world sites, though some were made up. He then walks through the steps to recreate the design element using clean semantic xhtml and CSS. One key benefit of this approach, apart from the increased flexibility, is that the amount of markup is greatly reduced in most cases as 1 pixel images and empty table cells are no longer needed.

Lest one think Cederholm is an anti-table zealot, he points out that there are situations where using a table is correct and semantic: when displaying tabular data of course. He then demonstrates how to use tables and CSS properly to get the proper layout without resorting to nested tables and empty table cells. The key is that the table should model the data, not the layout and he succeeds.

In the end, Bulletproof is a quick and worthwhile read with clear diagrams and plenty of css examples. There were some examples I wish he had taken further. For example, he mentions several uses for the dictionary list element (<dl>) to semantically mark up code, but only presents one example of styling a dictionary list. Understandable since this was not meant to be a complete compendium of CSS examples. Even so, I found plenty of good advice which I ended up applying to this site. The site responds well to enlargening the text (to a limit).

If you are a fan of “CSS Zen Garden”, this book would serve as a nice complement. “CSS Zen Garden” inspires designers with what is possible to do with CSS. “Bulletproof Web Design” provides some of the tools to get there.

My Blog Gets A Facelift

After completing two of the three books I said I would be reading in 2006, I decided to apply some of the lessons from the book Bulletproof Web Design by Dan Cederholm by slightly redesigning my site.

The change isn’t drastic on the surface, though I like to think it looks nicer and cleaner. Most of the changes are under the hood in the HTML and CSS. Most of you won’t notice since you read this via an RSS aggregator, but if you have a moment, take a look and let me know what you think.

A short book review is forthcoming.

Exception Handling Mistakes: Finally Block Does Not Require The Catch Block

While reviewing some code this weekend, I had the thought to do a search for the following string throughout the codebase, "catch(Exception" (using the regular expression search of course it looked more like "catch\s*(\s*Exception").

My intent was to take a look to see how badly Catch(Exception...) was being abused or if it was being used correctly. One interesting pattern I noticed frequently was the following snippet...

try
{
    fs = new FileStream(filename, FileMode.Create);
    //Do Something
}
catch(Exception ex)
{
    throw ex;
}
finally
{
    if(fs != null)
        fs.Close();
}

My guess is that the developer who wrote this didn’t realize that you don’t need a catch block in order to use a finally block. The finally block will ALWAYS fire whether or not there is an exception block. Also, this code is resetting the callstack on the exception as I’ve written about before.

This really just should be.

try
{
    fs = new FileStream(filename, FileMode.Create);
    //Do Something
}
finally
{
    if(fs != null)
        fs.Close();
}

Another common mistake I found is demonstrated by the following code snippet.

try
{
    //Do Something.
}
catch(Exception e)
{
    throw e;
}

This is another example where the author of the code is losing stack trace information. Even worse, there is no reason to even perform a try catch, since all that the developer is doing is rethrowing the exact exception being caught. I ended up removing the try/catch blocks everywhere I found this pattern.

Staples In My Head

When you hear the phrase, “use your head” you are typically being told to think. There are other uses of the head that are quite unwise. For example, trying to clear a soccer ball away from another player rushing in on the attack when you are a step too late. Unfortunately that’s exactly what I tried today.

My head just happened to get in the way of the shoulder of the onrushing soccer player when we both jumped to try and win the ball. It was really no contest as his shoulder won, leaving a nice inch long laceration on top of my scalp. Fortunately it wasn’t very deep and I was not knocked unconscious, though I bled a lot and had a nice Tom & Jerry bump on the head.

This earned me a trip to the ER which is NOTHING like the TV show. If it were, the show would have been cancelled after the first episode because I fail to see how interesting watching patients wait around for four hours for five to ten minutes of actual work would be.

In any case, the extremely busy doctor made quick work of cleaning out the wound and stapling it shut with two painful squeezes of the stapler (no local anesthesia). I hadn’t realized how helpful office supplies could be when applied to the head.

The doctor said I show no signs of a concussion and should be ready to play again in a few days as soon as I feel comfortable. I’m glad I’ll be able to play next week, but I won’t be using my head as much.

The Trouble With The Rat Race...

Read an interesting quote today, though it’s been around a while. It serves as a follow-up to my post about bringing back the 40hr work week.

The trouble with the rat race is that even if you win, you're still a rat. -- Lily Tomlin

Photography Lessons

I have a really old Kodak photography book laying around that delivers various tips for how to advance from your typical crapola™ snapshots into something worth boring your friends with on Flickr after your last vacation.

It is really too bad that I’ve forgotten everything the book had to say. Fortunately Robb Allen is starting a series of Photography lessons for our general photography improvement. Read lesson 1 and start taking better pics. Your friends and family will thank you for it.

My personal tip is to buy the biggest memory card you can afford, fill that sucker up when taking pictures, and delete vigorously before showing showing the pics off. Memory is getting cheaper and is way cheaper than paying for film and developing. Why settle for just one chance to get a great shot of your kid picking his nose when you can get three and keep the best. The odds are in your favor.

Just remember to delete vigorously because while memory is cheap, time isn’t.

My Vain Dog

I happened to notice my dog Twiggy apparently admiring herself in the mirror. At one point she was right up against the mirror looking at herself. By the time I got my camera, she had decided to on a more comfortable vantage point to check herself out.

Twiggy Mirror

And here I am working my ass off while she just lounges around. I really need to get her a j-o-b.

Websites Back In The Day

Scott Mitchell reminisces about Websites Back in the Day. You mean like this one1 Scott?

1 Creds to Mr. CodingHorror for finding this lovely lovely website that proves just because you can publish on the web, doesn’t mean you should. (Note: I do understand that particular site is satire, but I remember when that seemed to be the norm.)

A Huge Email Misunderstanding

Yesterday I received a call from my very exasperated father who recently has been helping my Korean mother learn how to use the web and web-based email.

  1. Dad

    Talk to your mother!

  2. Me

    Umm.. Ok. About what?

  3. Dad

    She got a nasty email and now she’s furious that I sent it to her. I tried to explain the concept of SPAM to her, but she doesn’t believe me. Maybe she’ll believe you.

  4. Me (groaning)

    Okay! Put her on.

My poor mother didn’t understand how anyone could get her email address and send her such filth, so therefore via deduction, it had to be my dad. She was shocked and appalled that he would send this to her.

I calmly explain to her how companies just love to sell your data to other less scrupulous companies who then send out emails to EVERYBODY. I get it, she gets it, dad gets it. Everyone gets it. I think she understands now, but I wonder if she’ll continue to bother with email now.

Subversion 1.3 Release Notes

Via Larkware News I noticed that Subversion 1.3 has been released. Looking at the release notes I noticed one thing in particular that caught my attention.

Official support for Windows '_svn' directories (client and language bindings)

The "_svn" hack is now officially supported: since some versions of ASP.NET don't allow directories beginning with dot (e.g., ".svn", the standard Subversion working copy administrative directory), the svn command line client and svnversion now treat the environment variable SVN_ASP_DOT_NET_HACK specially on Windows. If this variable is set (to any value), they will use "_svn" i