Lessons learned; starting a new project

I would like to share some things I have learned during the last few years while working as a freelance developer. These are some basic steps I use for almost every project…

Use a default folder structure

Whenever I start a project, I always start by creating a new folder in my projects folder. The contents of this folder looks like this:

01_managment, 02_docs, 03_interaction, 04_design, 05_development, 06_dropbox

I prefix the folders with a number so they are ordered in a reasonable fashion. I only use the ’06_dropbox’ folder if I work with someone else, so that one is not always required..

Use revision control software

This one is kind of obvious, but I put it in this list because I talked to a developer last week who still was working without any revision control software. So I really encourage you to use SVN or Git. Personally I prefer Git because it’s much more portable and you don’t need to have a server to save your revisions.

Automate the boring stuff

Another thing I learned is that clients like to see the current progress of the project and because they aren’t always around to look on your screen (which is a good thing) I upload my progress to my staging server. If you use a regular FTP program this could take a few minutes. First you open FTP, login to your server, find the right folder and upload. This manual uploading has two problems. The first is that it’s really slow. The second; you can make a lot of mistakes. Those two reasons made me choose for automation. So you probably wonder how you automate uploading a bunch of files?

The easiest way is use Automator (which ships with every Mac), and create a workflow which resembles this:

Alternatively you could do it the way I do it, this is slightly more dificult and requires a server with SSH access. The majority of shared hosting providers don’t provide you this kind of access unfortunately. If you have access, you could use this code sniplet to upload your project using RSync. This method is much faster because it does a comparison on byte level before starting the upload.

1
2
3
4
5
URL="http://clients.base42.nl/projectname/"
rsync --recursive --checksum --progress --compress --update --delete  folder-to-upload/ base42.nl:/home/jankeesvw/upload-to-this-folder/
echo $URL | pbcopy
echo "Upload to staging complete, link copied to clipboard: $URL"
/Users/jankees/bin/binaries/growlnotify -m "Upload complete, link copied to clipboard: $URL"

This defines a variable (line 1) then uploads it to my sever (line 2) copies the link to my clipboard (line 3) outputs a text to the console and to growl so I notice it’s done (line 4 and 5)

Use (and update) frameworks

When I work on projects I rely on open source projects; this is what I am currently using:

Another part of using frameworks is updating them, this can be a hard thing because it involves a lot of steps. That’s why I created an automation for this too! I put the shell script in a gist on github so you can see how it works. (Patrick Brouwer helped me building this). With my update script it’s really easy to update the external frameworks and I do this every few days when I work on a project.

Prepare a project to run in different environments

The last but not least is to prepare your projects to be ran in different environments. What this means is to be sure that your application is aware of it’s current location. To give an example. My flash project knows if it’s on the real server or on my local machine. If it’s on my local machine it generates some test data and shows some debug information. This does not mean I set something manualy everytime I publish to the server. This is some code that is smart enough to detect it’s current state. This is a glimp of what I use in Flash:

var browserpath : String = stage.loaderInfo.loaderURL;
var isLive : Boolean = true;
 
var localPaths : Array = [new RegExp("file://", ""), new RegExp("/localhost/", ""), new RegExp(".local/", "")];
for each (var regexp : RegExp in localPaths) {
    if (browserpath.match(regexp)) {
      isLive = false;
   }
}
 
if(isLive){
   trace("You are on a server!")
}else{
   trace("Hi developer")
}

I hope this helps to optimize your workflow. If you have other suggestions please let me know!


THE COMMENTS:



  • What David González Polán said 4 hours later:

    Nice post. I will try the folder structure on my devs.

  • What Patrick Brouwer said 10 hours later:

    Great post JK!

    Maybe an addition is the Version.as file that we create in pre compiling flash apps which determines the deployment state, using Ant.

    Well, as I’m writing this reply, there are a lot of workflow optimizations that I can think of right now.. like using a bootstrap file for instance and a lot more, but in general this post covers the most important workflow!!

  • What Patrick Pietens said 11 hours later:

    Check this out:
    var isLive:Boolean = new LocalConnection().domain != “localhost”;

  • What Eric-Paul said 24 hours later:

    Good setup. I’m personally not much into numbering folders, or making a lot of empty folders if they’re never used, but scaffolds have their uses. One difference I make to a standard setup is custom compiler arguments. I make two builds, one where a debug-flag is set to “true” and the other “false”. I use it in my Version.as class to distill into a simple Boolean, so I can ask Version.DEBUG to determine whether to show the debug stuff (prefilled fields, dummy content etc), or not. You have this in a domain check, but that would mean that downloading a def and running it locally exposes all the dummy content.

    That FTP stuff is a great hint by the way. Cheers, EP

  • What Sidney de Koning said 2 days later:

    Hi JK,

    Thanks for sharing these insights, realy cool.

    Cheers Sid

  • What Erik van Nieuwburg said 7 days later:

    Nice post JK!

    It looks like you could improve your workflow by automating your staging/production releases with Jenkins. We used that on the Allerhande project. Now they even run it on every project at Lukkien. It’s pretty brilliant stuff to be honost:

    http://jenkins-ci.org/

  • What David Marr said 11 days later:

    Good article sorry I mistakingly credited @brunofonzi in my linkback. I saw it on his twitter feed.

    The gitclone() function is pulling the specified directories from the given repo. I think alot of external libraries require building steps to generate the binary or shared library files.

    Is there a standard out there to determine how the package would need to be built? Ie, rake, ant, make.. depending on what files existed in the root dir. Would be an interesting feature!

Leave a Reply


one × 1 =